Commit 5760f7b94d36c6912ac19168b219c2a340826784

Authored by wuxw
1 parent f92fd6ac

小区下的功能修改完成

src/api/community/addCommunityPublicityApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +import { getCommunityId } from '@/api/community/communityApi'
  3 +
  4 +// 获取公示类型字典
  5 +export function getPublicityTypes() {
  6 + return new Promise((resolve, reject) => {
  7 + request({
  8 + url: '/dict/getDict',
  9 + method: 'get',
  10 + params: {
  11 + dictType: 'community_publicity',
  12 + dictCode: 'pub_type'
  13 + }
  14 + }).then(response => {
  15 + resolve(response.data)
  16 + }).catch(error => {
  17 + reject(error)
  18 + })
  19 + })
  20 +}
  21 +
  22 +// 保存社区公示
  23 +export function saveCommunityPublicity(data) {
  24 + data.communityId = getCommunityId()
  25 + return new Promise((resolve, reject) => {
  26 + request({
  27 + url: '/publicity.saveCommunityPublicity',
  28 + method: 'post',
  29 + data
  30 + }).then(response => {
  31 + resolve(response.data)
  32 + }).catch(error => {
  33 + reject(error)
  34 + })
  35 + })
  36 +}
  37 +
  38 +// 上传图片
  39 +export function uploadImage(data) {
  40 + data.communityId = getCommunityId()
  41 + return new Promise((resolve, reject) => {
  42 + request({
  43 + url: '/uploadFile/uploadImage',
  44 + method: 'post',
  45 + data,
  46 + headers: {
  47 + 'Content-Type': 'multipart/form-data'
  48 + }
  49 + }).then(response => {
  50 + resolve(response.data)
  51 + }).catch(error => {
  52 + reject(error)
  53 + })
  54 + })
  55 +}
0 56 \ No newline at end of file
... ...
src/api/community/communityPublicityManageApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +import { getCommunityId } from '@/api/community/communityApi'
  3 +
  4 +// 获取小区公示列表
  5 +export function getCommunityPublicityList(params) {
  6 + return new Promise((resolve, reject) => {
  7 + request({
  8 + url: '/publicity.listCommunityPublicity',
  9 + method: 'get',
  10 + params: {
  11 + ...params,
  12 + communityId: getCommunityId()
  13 + }
  14 + }).then(response => {
  15 + const res = response.data
  16 + resolve(res)
  17 + }).catch(error => {
  18 + reject(error)
  19 + })
  20 + })
  21 +}
  22 +
  23 +// 删除小区公示
  24 +export function deleteCommunityPublicity(data) {
  25 + return new Promise((resolve, reject) => {
  26 + request({
  27 + url: '/publicity.deleteCommunityPublicity',
  28 + method: 'post',
  29 + data: {
  30 + ...data,
  31 + communityId: getCommunityId()
  32 + }
  33 + }).then(response => {
  34 + const res = response.data
  35 + resolve(res)
  36 + }).catch(error => {
  37 + reject(error)
  38 + })
  39 + })
  40 +}
  41 +
  42 +// 获取字典数据
  43 +export function getDict(dictType, dictName) {
  44 + return new Promise((resolve, reject) => {
  45 + request({
  46 + url: '/dict.getDict',
  47 + method: 'get',
  48 + params: {
  49 + dictType,
  50 + dictName
  51 + }
  52 + }).then(response => {
  53 + const res = response.data
  54 + resolve(res)
  55 + }).catch(error => {
  56 + reject(error)
  57 + })
  58 + })
  59 +}
0 60 \ No newline at end of file
... ...
src/api/community/editCommunityPublicityApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +/**
  4 + * 更新社区公示信息
  5 + * @param {Object} data 公示信息
  6 + * @returns {Promise}
  7 + */
  8 +export function updateCommunityPublicity(data) {
  9 + return new Promise((resolve, reject) => {
  10 + request({
  11 + url: '/publicity.updateCommunityPublicity',
  12 + method: 'post',
  13 + data
  14 + }).then(response => {
  15 + const res = response.data
  16 + resolve(res)
  17 + }).catch(error => {
  18 + reject(error)
  19 + })
  20 + })
  21 +}
  22 +
  23 +/**
  24 + * 获取社区公示列表
  25 + * @param {Object} params 查询参数
  26 + * @returns {Promise}
  27 + */
  28 +export function listCommunityPublicity(params) {
  29 + return new Promise((resolve, reject) => {
  30 + request({
  31 + url: '/publicity.listCommunityPublicity',
  32 + method: 'get',
  33 + params
  34 + }).then(response => {
  35 + const res = response.data
  36 + resolve({
  37 + data: res.data || [],
  38 + total: res.total || 0
  39 + })
  40 + }).catch(error => {
  41 + reject(error)
  42 + })
  43 + })
  44 +}
  45 +
  46 +/**
  47 + * 上传文件
  48 + * @param {FormData} formData 文件表单数据
  49 + * @returns {Promise}
  50 + */
  51 +export function uploadFile(formData) {
  52 + return new Promise((resolve, reject) => {
  53 + request({
  54 + url: '/uploadFile',
  55 + method: 'post',
  56 + data: formData,
  57 + headers: {
  58 + 'Content-Type': 'multipart/form-data'
  59 + }
  60 + }).then(response => {
  61 + const res = response.data
  62 + resolve(res)
  63 + }).catch(error => {
  64 + reject(error)
  65 + })
  66 + })
  67 +}
  68 +
  69 +/**
  70 + * 获取单个公示详情
  71 + * @param {String} pubId 公示ID
  72 + * @returns {Promise}
  73 + */
  74 +export function getCommunityPublicityDetail(pubId) {
  75 + return new Promise((resolve, reject) => {
  76 + request({
  77 + url: '/publicity.getCommunityPublicity',
  78 + method: 'get',
  79 + params: { pubId }
  80 + }).then(response => {
  81 + const res = response.data
  82 + resolve(res.data)
  83 + }).catch(error => {
  84 + reject(error)
  85 + })
  86 + })
  87 +}
0 88 \ No newline at end of file
... ...
src/api/work/addItemReleaseViewApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +import { getCommunityId } from '@/api/community/communityApi'
  3 +
  4 +// 保存放行信息
  5 +export function saveItemRelease(data) {
  6 + return new Promise((resolve, reject) => {
  7 + request({
  8 + url: '/itemRelease.saveItemRelease',
  9 + method: 'post',
  10 + data: {
  11 + ...data,
  12 + communityId: getCommunityId()
  13 + }
  14 + }).then(response => {
  15 + resolve(response.data)
  16 + }).catch(error => {
  17 + reject(error)
  18 + })
  19 + })
  20 +}
  21 +
  22 +// 获取放行类型列表
  23 +export function listItemReleaseType(params) {
  24 + return new Promise((resolve, reject) => {
  25 + request({
  26 + url: '/itemRelease.listItemReleaseType',
  27 + method: 'get',
  28 + params: {
  29 + ...params,
  30 + communityId: getCommunityId()
  31 + }
  32 + }).then(response => {
  33 + resolve(response.data)
  34 + }).catch(error => {
  35 + reject(error)
  36 + })
  37 + })
  38 +}
  39 +
  40 +// 查询审批人信息
  41 +export function queryFirstAuditStaff(params) {
  42 + return new Promise((resolve, reject) => {
  43 + request({
  44 + url: '/oaWorkflow.queryFirstAuditStaff',
  45 + method: 'get',
  46 + params: {
  47 + ...params,
  48 + communityId: getCommunityId()
  49 + }
  50 + }).then(response => {
  51 + resolve(response.data)
  52 + }).catch(error => {
  53 + reject(error)
  54 + })
  55 + })
  56 +}
  57 +
  58 +// 查询员工信息
  59 +export function queryStaffInfos(params) {
  60 + return new Promise((resolve, reject) => {
  61 + request({
  62 + url: '/query.staff.infos',
  63 + method: 'get',
  64 + params: {
  65 + ...params,
  66 + communityId: getCommunityId()
  67 + }
  68 + }).then(response => {
  69 + resolve(response.data)
  70 + }).catch(error => {
  71 + reject(error)
  72 + })
  73 + })
  74 +}
  75 +
  76 +// 获取组织树
  77 +export function listOrgTree(params) {
  78 + return new Promise((resolve, reject) => {
  79 + request({
  80 + url: '/org.listOrgTree',
  81 + method: 'get',
  82 + params: {
  83 + ...params,
  84 + communityId: getCommunityId()
  85 + }
  86 + }).then(response => {
  87 + resolve(response.data)
  88 + }).catch(error => {
  89 + reject(error)
  90 + })
  91 + })
  92 +}
0 93 \ No newline at end of file
... ...
src/api/work/itemReleaseManageApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +import { getCommunityId } from '@/api/community/communityApi'
  3 +
  4 +// 获取物品放行列表
  5 +export function listItemRelease(params) {
  6 + return new Promise((resolve, reject) => {
  7 + const communityId = getCommunityId()
  8 + request({
  9 + url: '/itemRelease.listItemRelease',
  10 + method: 'get',
  11 + params: {
  12 + ...params,
  13 + communityId
  14 + }
  15 + }).then(response => {
  16 + const res = response.data
  17 + resolve(res)
  18 + }).catch(error => {
  19 + reject(error)
  20 + })
  21 + })
  22 +}
  23 +
  24 +// 获取物品放行类型列表
  25 +export function listItemReleaseType(params) {
  26 + return new Promise((resolve, reject) => {
  27 + const communityId = getCommunityId()
  28 + request({
  29 + url: '/itemRelease.listItemReleaseType',
  30 + method: 'get',
  31 + params: {
  32 + ...params,
  33 + communityId
  34 + }
  35 + }).then(response => {
  36 + const res = response.data
  37 + resolve(res)
  38 + }).catch(error => {
  39 + reject(error)
  40 + })
  41 + })
  42 +}
  43 +
  44 +// 更新物品放行信息
  45 +export function updateItemRelease(data) {
  46 + return new Promise((resolve, reject) => {
  47 + const communityId = getCommunityId()
  48 + request({
  49 + url: '/itemRelease.updateItemRelease',
  50 + method: 'post',
  51 + data: {
  52 + ...data,
  53 + communityId
  54 + }
  55 + }).then(response => {
  56 + const res = response.data
  57 + resolve(res)
  58 + }).catch(error => {
  59 + reject(error)
  60 + })
  61 + })
  62 +}
  63 +
  64 +// 删除物品放行
  65 +export function deleteItemRelease(data) {
  66 + return new Promise((resolve, reject) => {
  67 + const communityId = getCommunityId()
  68 + request({
  69 + url: '/itemRelease.deleteItemRelease',
  70 + method: 'post',
  71 + data: {
  72 + ...data,
  73 + communityId
  74 + }
  75 + }).then(response => {
  76 + const res = response.data
  77 + resolve(res)
  78 + }).catch(error => {
  79 + reject(error)
  80 + })
  81 + })
  82 +}
  83 +
  84 +// 获取物品放行物品列表
  85 +export function listItemReleaseRes(params) {
  86 + return new Promise((resolve, reject) => {
  87 + const communityId = getCommunityId()
  88 + request({
  89 + url: '/itemRelease.listItemReleaseRes',
  90 + method: 'get',
  91 + params: {
  92 + ...params,
  93 + communityId
  94 + }
  95 + }).then(response => {
  96 + const res = response.data
  97 + resolve(res)
  98 + }).catch(error => {
  99 + reject(error)
  100 + })
  101 + })
  102 +}
0 103 \ No newline at end of file
... ...
src/api/work/itemReleaseTypeManageApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +import { getCommunityId } from '@/api/community/communityApi'
  3 +
  4 +// 获取放行类型列表
  5 +export function listItemReleaseType(params) {
  6 + return new Promise((resolve, reject) => {
  7 + request({
  8 + url: '/itemRelease.listItemReleaseType',
  9 + method: 'get',
  10 + params: {
  11 + ...params,
  12 + communityId: getCommunityId()
  13 + }
  14 + }).then(response => {
  15 + const res = response.data
  16 + resolve(res)
  17 + }).catch(error => {
  18 + reject(error)
  19 + })
  20 + })
  21 +}
  22 +
  23 +// 添加放行类型
  24 +export function saveItemReleaseType(data) {
  25 + return new Promise((resolve, reject) => {
  26 + request({
  27 + url: '/itemRelease.saveItemReleaseType',
  28 + method: 'post',
  29 + data: {
  30 + ...data,
  31 + communityId: getCommunityId()
  32 + }
  33 + }).then(response => {
  34 + const res = response.data
  35 + resolve(res)
  36 + }).catch(error => {
  37 + reject(error)
  38 + })
  39 + })
  40 +}
  41 +
  42 +// 修改放行类型
  43 +export function updateItemReleaseType(data) {
  44 + return new Promise((resolve, reject) => {
  45 + request({
  46 + url: '/itemRelease.updateItemReleaseType',
  47 + method: 'post',
  48 + data: {
  49 + ...data,
  50 + communityId: getCommunityId()
  51 + }
  52 + }).then(response => {
  53 + const res = response.data
  54 + resolve(res)
  55 + }).catch(error => {
  56 + reject(error)
  57 + })
  58 + })
  59 +}
  60 +
  61 +// 删除放行类型
  62 +export function deleteItemReleaseType(data) {
  63 + return new Promise((resolve, reject) => {
  64 + request({
  65 + url: '/itemRelease.deleteItemReleaseType',
  66 + method: 'post',
  67 + data: {
  68 + ...data,
  69 + communityId: getCommunityId()
  70 + }
  71 + }).then(response => {
  72 + const res = response.data
  73 + resolve(res)
  74 + }).catch(error => {
  75 + reject(error)
  76 + })
  77 + })
  78 +}
  79 +
  80 +// 部署流程
  81 +export function deployModel(data) {
  82 + return new Promise((resolve, reject) => {
  83 + request({
  84 + url: '/workflow/deployModel',
  85 + method: 'post',
  86 + data
  87 + }).then(response => {
  88 + const res = response.data
  89 + resolve(res)
  90 + }).catch(error => {
  91 + reject(error)
  92 + })
  93 + })
  94 +}
0 95 \ No newline at end of file
... ...
src/components/community/deleteCommunityPublicity.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('communityPublicityManage.deleteTitle')"
  4 + :visible.sync="visible"
  5 + width="500px"
  6 + :before-close="handleClose"
  7 + >
  8 + <div class="delete-content">
  9 + <p>{{ $t('communityPublicityManage.deleteConfirm') }}</p>
  10 + </div>
  11 + <div slot="footer" class="dialog-footer">
  12 + <el-button @click="handleClose">{{ $t('common.cancel') }}</el-button>
  13 + <el-button type="primary" @click="handleConfirm" :loading="loading">
  14 + {{ $t('common.confirm') }}
  15 + </el-button>
  16 + </div>
  17 + </el-dialog>
  18 +</template>
  19 +
  20 +<script>
  21 +import { deleteCommunityPublicity } from '@/api/community/communityPublicityManageApi'
  22 +import { getCommunityId } from '@/api/community/communityApi'
  23 +
  24 +export default {
  25 + name: 'DeleteCommunityPublicity',
  26 + data() {
  27 + return {
  28 + visible: false,
  29 + loading: false,
  30 + currentItem: null
  31 + }
  32 + },
  33 + methods: {
  34 + open(item) {
  35 + this.currentItem = item
  36 + this.visible = true
  37 + },
  38 + handleClose() {
  39 + this.visible = false
  40 + },
  41 + async handleConfirm() {
  42 + try {
  43 + this.loading = true
  44 + const params = {
  45 + pubId: this.currentItem.pubId,
  46 + communityId: getCommunityId()
  47 + }
  48 + await deleteCommunityPublicity(params)
  49 + this.$message.success(this.$t('communityPublicityManage.deleteSuccess'))
  50 + this.$emit('success')
  51 + this.handleClose()
  52 + } catch (error) {
  53 + console.error('删除失败:', error)
  54 + this.$message.error(error.message || this.$t('communityPublicityManage.deleteError'))
  55 + } finally {
  56 + this.loading = false
  57 + }
  58 + }
  59 + }
  60 +}
  61 +</script>
  62 +
  63 +<style lang="scss" scoped>
  64 +.delete-content {
  65 + text-align: center;
  66 + font-size: 16px;
  67 + padding: 20px 0;
  68 +}
  69 +
  70 +.dialog-footer {
  71 + text-align: right;
  72 +}
  73 +</style>
0 74 \ No newline at end of file
... ...
src/components/community/uploadImageUrl.vue
1 1 <template>
2   - <div class="uploadImage">
  2 + <div class="upload-image-container">
3 3 <div v-for="(image, index) in photos" :key="index" class="image-item">
4   - <img :src="image" width="100" height="100" />
5   - <i class="el-icon-close remove-icon" @click="removeImage(index)"></i>
  4 + <el-image
  5 + :src="image.url || image"
  6 + fit="cover"
  7 + style="width: 100px; height: 100px"
  8 + :preview-src-list="[image.url || image]"
  9 + >
  10 + <div slot="error" class="image-slot">
  11 + <i class="el-icon-picture-outline"></i>
  12 + </div>
  13 + </el-image>
  14 + <i
  15 + class="el-icon-delete remove-icon"
  16 + @click="removeImage(index)"
  17 + ></i>
6 18 </div>
7   - <div v-if="photos.length < imageCount" class="upload-button" @click="triggerUpload">
  19 + <div
  20 + v-if="photos.length < imageCount"
  21 + class="upload-button"
  22 + @click="triggerUpload"
  23 + >
8 24 <i class="el-icon-plus"></i>
9 25 </div>
10   - <input type="file" ref="fileInput" accept="image/*" hidden @change="handleFileChange">
  26 + <input
  27 + type="file"
  28 + ref="fileInput"
  29 + accept="image/*"
  30 + hidden
  31 + @change="handleFileChange"
  32 + />
11 33 </div>
12 34 </template>
13 35  
14 36 <script>
  37 +import { uploadImage } from '@/api/community/addCommunityPublicityApi'
  38 +
15 39 export default {
16 40 name: 'UploadImageUrl',
17 41 props: {
18 42 imageCount: {
19 43 type: Number,
20 44 default: 99
  45 + },
  46 + callBackListener: {
  47 + type: String,
  48 + required: true
  49 + },
  50 + callBackFunction: {
  51 + type: String,
  52 + required: true
21 53 }
22 54 },
23 55 data() {
... ... @@ -28,95 +60,124 @@ export default {
28 60 },
29 61 watch: {
30 62 photosUrl: {
31   - handler(val) {
32   - this.$emit('update:photosUrl', val)
33   - },
34   - deep: true
  63 + deep: true,
  64 + handler(newVal) {
  65 + this.$emit(this.callBackFunction, newVal)
  66 + }
35 67 }
36 68 },
37 69 methods: {
38 70 triggerUpload() {
39 71 this.$refs.fileInput.click()
40 72 },
41   - handleFileChange(event) {
42   - const file = event.target.files[0]
43   - if (!file) return
44   -
  73 + async handleFileChange(event) {
  74 + const files = event.target.files
  75 + if (!files || files.length === 0) return
  76 +
  77 + const file = files[0]
45 78 if (file.size > 2 * 1024 * 1024) {
46   - this.$message.error(this.$t('enterCommunity.fileSizeError'))
  79 + this.$message.error(this.$t('uploadImage.fileSizeError'))
47 80 return
48 81 }
49   -
50   - const reader = new FileReader()
51   - reader.onload = (e) => {
52   - this.photos.push(e.target.result)
53   - this.uploadImage(file)
  82 +
  83 + try {
  84 + // Preview image
  85 + const reader = new FileReader()
  86 + reader.onload = (e) => {
  87 + this.photos.push(e.target.result)
  88 + }
  89 + reader.readAsDataURL(file)
  90 +
  91 + // Upload image
  92 + const formData = new FormData()
  93 + formData.append('uploadFile', file)
  94 + const response = await uploadImage(formData)
  95 + this.photosUrl.push(response.data)
  96 + } catch (error) {
  97 + this.$message.error(this.$t('uploadImage.uploadError'))
  98 + } finally {
  99 + event.target.value = ''
54 100 }
55   - reader.readAsDataURL(file)
56   -
57   - // 重置input
58   - event.target.value = null
59 101 },
60 102 removeImage(index) {
61 103 this.photos.splice(index, 1)
62 104 this.photosUrl.splice(index, 1)
63 105 },
64   - uploadImage(file) {
65   - const formData = new FormData()
66   - formData.append('uploadFile', file)
67   - formData.append('communityId', this.$store.getters.currentCommunity.communityId)
68   -
69   - this.$http.upload('uploadFile', 'uploadImage', formData, {
70   - headers: { 'Content-Type': 'multipart/form-data' }
71   - }).then(res => {
72   - const data = JSON.parse(res.data)
73   - this.photosUrl.push({
74   - fileId: data.fileId,
75   - url: `/callComponent/download/getFile/file?fileId=${data.fileId}`
76   - })
77   - }).catch(err => {
78   - this.$message.error(this.$t('enterCommunity.uploadError'))
79   - })
  106 + clearImages() {
  107 + this.photos = []
  108 + this.photosUrl = []
80 109 },
81   - setPhotos(photos) {
82   - this.photos = photos
  110 + setImages(images) {
  111 + this.clearImages()
  112 + images.forEach(image => {
  113 + if (typeof image === 'string') {
  114 + this.photos.push(image)
  115 + this.photosUrl.push({ fileId: image, url: image })
  116 + } else {
  117 + this.photos.push(image.url)
  118 + this.photosUrl.push(image)
  119 + }
  120 + })
83 121 }
84 122 }
85 123 }
86 124 </script>
87 125  
88   -<style scoped>
89   -.uploadImage {
  126 +<style lang="scss" scoped>
  127 +.upload-image-container {
90 128 display: flex;
91 129 flex-wrap: wrap;
92 130 gap: 10px;
93   -}
94   -.image-item {
95   - position: relative;
96   - display: inline-block;
97   -}
98   -.remove-icon {
99   - position: absolute;
100   - top: -10px;
101   - right: -10px;
102   - color: #f56c6c;
103   - cursor: pointer;
104   - background: white;
105   - border-radius: 50%;
106   -}
107   -.upload-button {
108   - width: 100px;
109   - height: 100px;
110   - border: 1px dashed #dcdfe6;
111   - border-radius: 4px;
112   - display: flex;
113   - align-items: center;
114   - justify-content: center;
115   - font-size: 24px;
116   - color: #8c939d;
117   - cursor: pointer;
118   -}
119   -.upload-button:hover {
120   - border-color: #409eff;
  131 +
  132 + .image-item {
  133 + position: relative;
  134 + margin-right: 10px;
  135 + margin-bottom: 10px;
  136 +
  137 + .remove-icon {
  138 + position: absolute;
  139 + top: -10px;
  140 + right: -10px;
  141 + color: #f56c6c;
  142 + background: #fff;
  143 + border-radius: 50%;
  144 + cursor: pointer;
  145 + font-size: 16px;
  146 + z-index: 1;
  147 +
  148 + &:hover {
  149 + color: #f78989;
  150 + }
  151 + }
  152 + }
  153 +
  154 + .upload-button {
  155 + width: 100px;
  156 + height: 100px;
  157 + border: 1px dashed #dcdfe6;
  158 + border-radius: 4px;
  159 + display: flex;
  160 + align-items: center;
  161 + justify-content: center;
  162 + cursor: pointer;
  163 + color: #909399;
  164 + font-size: 24px;
  165 +
  166 + &:hover {
  167 + border-color: #409eff;
  168 + color: #409eff;
  169 + }
  170 + }
  171 +
  172 + .image-slot {
  173 + display: flex;
  174 + justify-content: center;
  175 + align-items: center;
  176 + width: 100%;
  177 + height: 100%;
  178 + background: #f5f7fa;
  179 + color: #909399;
  180 + font-size: 30px;
  181 + }
121 182 }
122 183 </style>
123 184 \ No newline at end of file
... ...
src/components/community/viewImage.vue
1 1 <template>
2   - <div id="view-image" v-show="visible">
  2 + <div v-show="visible" class="image-viewer">
3 3 <div class="image-container">
4   - <img :src="imageUrl" :width="imageWidth" :height="imageHeight" @error="handleImageError" />
5   - <span class="el-icon-close close-icon" @click="close" />
  4 + <img
  5 + :src="imageUrl"
  6 + :style="{
  7 + width: imageWidth + 'px',
  8 + height: imageHeight + 'px'
  9 + }"
  10 + @error="handleImageError"
  11 + />
  12 + <i class="el-icon-close close-icon" @click="close"></i>
6 13 </div>
7 14 </div>
8 15 </template>
... ... @@ -23,20 +30,24 @@ export default {
23 30 this.imageUrl = url
24 31 this.visible = true
25 32 this.enterFullscreen()
  33 +
  34 + // 计算图片宽高比例
26 35 const img = new Image()
27 36 img.src = url
28 37 img.onload = () => {
29   - const imgScale = img.width / img.height
30   - this.imageWidth = 800
31   - this.imageHeight = 800 / imgScale
  38 + const ratio = img.width / img.height
  39 + this.imageHeight = this.imageWidth / ratio
32 40 }
33 41 },
34 42 close() {
35 43 this.exitFullscreen()
36 44 this.visible = false
37 45 },
  46 + handleImageError(e) {
  47 + e.target.src = '/img/noPhoto.jpg'
  48 + },
38 49 enterFullscreen() {
39   - const element = document.getElementById('view-image')
  50 + const element = this.$el
40 51 if (element.requestFullscreen) {
41 52 element.requestFullscreen()
42 53 } else if (element.mozRequestFullScreen) {
... ... @@ -55,16 +66,13 @@ export default {
55 66 } else if (document.webkitExitFullscreen) {
56 67 document.webkitExitFullscreen()
57 68 }
58   - },
59   - handleImageError(e) {
60   - e.target.src = '/img/noPhoto.jpg'
61 69 }
62 70 }
63 71 }
64 72 </script>
65 73  
66   -<style scoped>
67   -#view-image {
  74 +<style lang="scss" scoped>
  75 +.image-viewer {
68 76 position: fixed;
69 77 top: 0;
70 78 left: 0;
... ... @@ -75,21 +83,28 @@ export default {
75 83 display: flex;
76 84 justify-content: center;
77 85 align-items: center;
78   -}
79 86  
80   -.image-container {
81   - position: relative;
82   - background-color: #fff;
83   - padding: 20px;
84   - border-radius: 4px;
85   -}
  87 + .image-container {
  88 + position: relative;
  89 + background-color: #fff;
  90 + padding: 20px;
  91 + border-radius: 4px;
  92 +
  93 + img {
  94 + max-width: 80vw;
  95 + max-height: 80vh;
  96 + object-fit: contain;
  97 + }
86 98  
87   -.close-icon {
88   - position: absolute;
89   - right: 20px;
90   - top: 20px;
91   - font-size: 20px;
92   - color: red;
93   - cursor: pointer;
  99 + .close-icon {
  100 + position: absolute;
  101 + top: 10px;
  102 + right: 10px;
  103 + font-size: 24px;
  104 + color: #f56c6c;
  105 + cursor: pointer;
  106 + z-index: 1;
  107 + }
  108 + }
94 109 }
95 110 </style>
96 111 \ No newline at end of file
... ...
src/components/work/addItemReleaseType.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('itemReleaseTypeManage.add.title')"
  4 + :visible.sync="visible"
  5 + width="50%"
  6 + @close="handleClose"
  7 + >
  8 + <el-form
  9 + ref="form"
  10 + :model="form"
  11 + :rules="rules"
  12 + label-width="120px"
  13 + label-position="right"
  14 + >
  15 + <el-form-item
  16 + :label="$t('itemReleaseTypeManage.form.typeName')"
  17 + prop="typeName"
  18 + >
  19 + <el-input
  20 + v-model="form.typeName"
  21 + :placeholder="$t('itemReleaseTypeManage.form.typeNamePlaceholder')"
  22 + />
  23 + </el-form-item>
  24 + <el-form-item
  25 + :label="$t('itemReleaseTypeManage.form.remark')"
  26 + prop="remark"
  27 + >
  28 + <el-input
  29 + v-model="form.remark"
  30 + type="textarea"
  31 + :rows="3"
  32 + :placeholder="$t('itemReleaseTypeManage.form.remarkPlaceholder')"
  33 + />
  34 + </el-form-item>
  35 + </el-form>
  36 +
  37 + <span slot="footer" class="dialog-footer">
  38 + <el-button @click="visible = false">
  39 + {{ $t('common.cancel') }}
  40 + </el-button>
  41 + <el-button type="primary" @click="handleSubmit">
  42 + {{ $t('common.confirm') }}
  43 + </el-button>
  44 + </span>
  45 + </el-dialog>
  46 +</template>
  47 +
  48 +<script>
  49 +import { saveItemReleaseType } from '@/api/work/itemReleaseTypeManageApi'
  50 +import { getCommunityId } from '@/api/community/communityApi'
  51 +
  52 +export default {
  53 + name: 'AddItemReleaseType',
  54 + data() {
  55 + return {
  56 + visible: false,
  57 + form: {
  58 + typeName: '',
  59 + remark: '',
  60 + communityId: ''
  61 + },
  62 + rules: {
  63 + typeName: [
  64 + { required: true, message: this.$t('itemReleaseTypeManage.validate.typeNameRequired'), trigger: 'blur' },
  65 + { max: 30, message: this.$t('itemReleaseTypeManage.validate.typeNameMaxLength'), trigger: 'blur' }
  66 + ],
  67 + remark: [
  68 + { required: true, message: this.$t('itemReleaseTypeManage.validate.remarkRequired'), trigger: 'blur' },
  69 + { max: 512, message: this.$t('itemReleaseTypeManage.validate.remarkMaxLength'), trigger: 'blur' }
  70 + ]
  71 + }
  72 + }
  73 + },
  74 + methods: {
  75 + open() {
  76 + this.visible = true
  77 + this.form.communityId = getCommunityId()
  78 + this.$nextTick(() => {
  79 + this.$refs.form.resetFields()
  80 + })
  81 + },
  82 + handleClose() {
  83 + this.$refs.form.resetFields()
  84 + },
  85 + handleSubmit() {
  86 + this.$refs.form.validate(async valid => {
  87 + if (valid) {
  88 + try {
  89 + await saveItemReleaseType(this.form)
  90 + this.$message.success(this.$t('itemReleaseTypeManage.add.success'))
  91 + this.visible = false
  92 + this.$emit('success')
  93 + } catch (error) {
  94 + this.$message.error(this.$t('itemReleaseTypeManage.add.error'))
  95 + }
  96 + }
  97 + })
  98 + }
  99 + }
  100 +}
  101 +</script>
0 102 \ No newline at end of file
... ...
src/components/work/deleteItemRelease.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('common.confirmOperation')"
  4 + :visible.sync="visible"
  5 + width="30%"
  6 + @close="handleClose"
  7 + >
  8 + <div style="text-align: center">
  9 + <p>{{ $t('itemReleaseManage.delete.confirmDelete') }}</p>
  10 + </div>
  11 + <span slot="footer" class="dialog-footer">
  12 + <el-button @click="visible = false">
  13 + {{ $t('common.cancel') }}
  14 + </el-button>
  15 + <el-button type="primary" @click="handleConfirm">
  16 + {{ $t('common.confirmDelete') }}
  17 + </el-button>
  18 + </span>
  19 + </el-dialog>
  20 +</template>
  21 +
  22 +<script>
  23 +import { getCommunityId } from '@/api/community/communityApi'
  24 +import { deleteItemRelease } from '@/api/work/itemReleaseManageApi'
  25 +
  26 +export default {
  27 + name: 'DeleteItemRelease',
  28 + data() {
  29 + return {
  30 + visible: false,
  31 + communityId: '',
  32 + currentItem: {}
  33 + }
  34 + },
  35 + created() {
  36 + this.communityId = getCommunityId()
  37 + },
  38 + methods: {
  39 + open(item) {
  40 + this.currentItem = {
  41 + ...item,
  42 + communityId: this.communityId
  43 + }
  44 + this.visible = true
  45 + },
  46 + handleClose() {
  47 + this.currentItem = {}
  48 + },
  49 + async handleConfirm() {
  50 + try {
  51 + await deleteItemRelease(this.currentItem)
  52 + this.$message.success(this.$t('common.deleteSuccess'))
  53 + this.$emit('success')
  54 + this.visible = false
  55 + } catch (error) {
  56 + console.error('删除物品放行失败:', error)
  57 + }
  58 + }
  59 + }
  60 +}
  61 +</script>
0 62 \ No newline at end of file
... ...
src/components/work/deleteItemReleaseType.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('itemReleaseTypeManage.delete.title')"
  4 + :visible.sync="visible"
  5 + width="30%"
  6 + center
  7 + >
  8 + <div class="text-center">
  9 + <p>{{ $t('itemReleaseTypeManage.delete.confirmText') }}</p>
  10 + </div>
  11 + <span slot="footer" class="dialog-footer">
  12 + <el-button @click="visible = false">
  13 + {{ $t('common.cancel') }}
  14 + </el-button>
  15 + <el-button type="danger" @click="handleConfirm">
  16 + {{ $t('common.confirm') }}
  17 + </el-button>
  18 + </span>
  19 + </el-dialog>
  20 +</template>
  21 +
  22 +<script>
  23 +import { deleteItemReleaseType } from '@/api/work/itemReleaseTypeManageApi'
  24 +import { getCommunityId } from '@/api/community/communityApi'
  25 +
  26 +export default {
  27 + name: 'DeleteItemReleaseType',
  28 + data() {
  29 + return {
  30 + visible: false,
  31 + form: {
  32 + typeId: '',
  33 + communityId: ''
  34 + }
  35 + }
  36 + },
  37 + methods: {
  38 + open(row) {
  39 + this.form = {
  40 + typeId: row.typeId,
  41 + communityId: getCommunityId()
  42 + }
  43 + this.visible = true
  44 + },
  45 + async handleConfirm() {
  46 + try {
  47 + await deleteItemReleaseType(this.form)
  48 + this.$message.success(this.$t('itemReleaseTypeManage.delete.success'))
  49 + this.visible = false
  50 + this.$emit('success')
  51 + } catch (error) {
  52 + this.$message.error(this.$t('itemReleaseTypeManage.delete.error'))
  53 + }
  54 + }
  55 + }
  56 +}
  57 +</script>
0 58 \ No newline at end of file
... ...
src/components/work/editItemRelease.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('itemReleaseManage.edit.title')"
  4 + :visible.sync="visible"
  5 + width="60%"
  6 + @close="handleClose"
  7 + >
  8 + <el-form
  9 + ref="form"
  10 + :model="formData"
  11 + :rules="rules"
  12 + label-width="120px"
  13 + label-position="right"
  14 + >
  15 + <el-form-item
  16 + :label="$t('itemReleaseManage.form.releaseType')"
  17 + prop="typeId"
  18 + >
  19 + <el-select
  20 + v-model="formData.typeId"
  21 + :placeholder="$t('itemReleaseManage.placeholder.requiredSelect')"
  22 + style="width: 100%"
  23 + >
  24 + <el-option
  25 + v-for="item in releaseTypes"
  26 + :key="item.typeId"
  27 + :label="item.typeName"
  28 + :value="item.typeId"
  29 + />
  30 + </el-select>
  31 + </el-form-item>
  32 +
  33 + <el-form-item
  34 + :label="$t('itemReleaseManage.form.applyCompany')"
  35 + prop="applyCompany"
  36 + >
  37 + <el-input
  38 + v-model="formData.applyCompany"
  39 + :placeholder="$t('itemReleaseManage.placeholder.requiredInput')"
  40 + />
  41 + </el-form-item>
  42 +
  43 + <el-form-item
  44 + :label="$t('itemReleaseManage.form.applyPerson')"
  45 + prop="applyPerson"
  46 + >
  47 + <el-input
  48 + v-model="formData.applyPerson"
  49 + :placeholder="$t('itemReleaseManage.placeholder.requiredInput')"
  50 + />
  51 + </el-form-item>
  52 +
  53 + <el-form-item
  54 + :label="$t('itemReleaseManage.form.idCard')"
  55 + prop="idCard"
  56 + >
  57 + <el-input
  58 + v-model="formData.idCard"
  59 + :placeholder="$t('itemReleaseManage.placeholder.requiredInput')"
  60 + maxlength="18"
  61 + />
  62 + </el-form-item>
  63 +
  64 + <el-form-item
  65 + :label="$t('itemReleaseManage.form.phone')"
  66 + prop="applyTel"
  67 + >
  68 + <el-input
  69 + v-model="formData.applyTel"
  70 + :placeholder="$t('itemReleaseManage.placeholder.requiredInput')"
  71 + maxlength="11"
  72 + />
  73 + </el-form-item>
  74 +
  75 + <el-form-item
  76 + :label="$t('itemReleaseManage.form.passTime')"
  77 + prop="passTime"
  78 + >
  79 + <el-input
  80 + v-model="formData.passTime"
  81 + :placeholder="$t('itemReleaseManage.placeholder.requiredInput')"
  82 + />
  83 + </el-form-item>
  84 +
  85 + <el-form-item
  86 + :label="$t('itemReleaseManage.form.releaseItems')"
  87 + prop="resName"
  88 + >
  89 + <el-input
  90 + v-model="formData.resName"
  91 + :placeholder="$t('itemReleaseManage.placeholder.requiredInput')"
  92 + />
  93 + </el-form-item>
  94 +
  95 + <el-form-item
  96 + :label="$t('itemReleaseManage.form.itemAmount')"
  97 + prop="amount"
  98 + >
  99 + <el-input
  100 + v-model="formData.amount"
  101 + :placeholder="$t('itemReleaseManage.placeholder.requiredInput')"
  102 + />
  103 + </el-form-item>
  104 +
  105 + <el-form-item
  106 + :label="$t('itemReleaseManage.form.status')"
  107 + prop="state"
  108 + >
  109 + <el-select
  110 + v-model="formData.state"
  111 + :placeholder="$t('itemReleaseManage.placeholder.requiredSelect')"
  112 + style="width: 100%"
  113 + >
  114 + <el-option
  115 + :label="$t('itemReleaseManage.status.waiting')"
  116 + value="W"
  117 + />
  118 + <el-option
  119 + :label="$t('itemReleaseManage.status.processing')"
  120 + value="D"
  121 + />
  122 + <el-option
  123 + :label="$t('itemReleaseManage.status.completed')"
  124 + value="C"
  125 + />
  126 + <el-option
  127 + :label="$t('itemReleaseManage.status.failed')"
  128 + value="F"
  129 + />
  130 + </el-select>
  131 + </el-form-item>
  132 +
  133 + <el-form-item
  134 + :label="$t('itemReleaseManage.form.carNumber')"
  135 + prop="carNum"
  136 + >
  137 + <el-input
  138 + v-model="formData.carNum"
  139 + :placeholder="$t('itemReleaseManage.placeholder.requiredInput')"
  140 + />
  141 + </el-form-item>
  142 +
  143 + <el-form-item
  144 + :label="$t('itemReleaseManage.form.remark')"
  145 + prop="remark"
  146 + >
  147 + <el-input
  148 + v-model="formData.remark"
  149 + type="textarea"
  150 + :placeholder="$t('itemReleaseManage.placeholder.optionalInput')"
  151 + />
  152 + </el-form-item>
  153 + </el-form>
  154 +
  155 + <span slot="footer" class="dialog-footer">
  156 + <el-button @click="visible = false">
  157 + {{ $t('common.cancel') }}
  158 + </el-button>
  159 + <el-button type="primary" @click="handleSubmit">
  160 + {{ $t('common.save') }}
  161 + </el-button>
  162 + </span>
  163 + </el-dialog>
  164 +</template>
  165 +
  166 +<script>
  167 +import { getCommunityId } from '@/api/community/communityApi'
  168 +import { updateItemRelease, listItemReleaseType } from '@/api/work/itemReleaseManageApi'
  169 +
  170 +export default {
  171 + name: 'EditItemRelease',
  172 + data() {
  173 + return {
  174 + visible: false,
  175 + communityId: '',
  176 + releaseTypes: [],
  177 + formData: {
  178 + irId: '',
  179 + typeId: '',
  180 + applyCompany: '',
  181 + applyPerson: '',
  182 + idCard: '',
  183 + applyTel: '',
  184 + passTime: '',
  185 + resName: '',
  186 + amount: '',
  187 + state: '',
  188 + carNum: '',
  189 + remark: '',
  190 + communityId: ''
  191 + },
  192 + rules: {
  193 + typeId: [
  194 + { required: true, message: this.$t('itemReleaseManage.validate.required'), trigger: 'blur' },
  195 + { max: 30, message: this.$t('itemReleaseManage.validate.maxLength30'), trigger: 'blur' }
  196 + ],
  197 + applyCompany: [
  198 + { required: true, message: this.$t('itemReleaseManage.validate.required'), trigger: 'blur' },
  199 + { max: 64, message: this.$t('itemReleaseManage.validate.maxLength64'), trigger: 'blur' }
  200 + ],
  201 + applyPerson: [
  202 + { required: true, message: this.$t('itemReleaseManage.validate.required'), trigger: 'blur' },
  203 + { max: 64, message: this.$t('itemReleaseManage.validate.maxLength64'), trigger: 'blur' }
  204 + ],
  205 + idCard: [
  206 + { required: true, message: this.$t('itemReleaseManage.validate.required'), trigger: 'blur' },
  207 + { max: 18, message: this.$t('itemReleaseManage.validate.maxLength18'), trigger: 'blur' }
  208 + ],
  209 + applyTel: [
  210 + { required: true, message: this.$t('itemReleaseManage.validate.required'), trigger: 'blur' },
  211 + { max: 11, message: this.$t('itemReleaseManage.validate.maxLength11'), trigger: 'blur' }
  212 + ],
  213 + passTime: [
  214 + { required: true, message: this.$t('itemReleaseManage.validate.required'), trigger: 'blur' },
  215 + { max: 12, message: this.$t('itemReleaseManage.validate.maxLength12'), trigger: 'blur' }
  216 + ],
  217 + resName: [
  218 + { required: true, message: this.$t('itemReleaseManage.validate.required'), trigger: 'blur' },
  219 + { max: 512, message: this.$t('itemReleaseManage.validate.maxLength512'), trigger: 'blur' }
  220 + ],
  221 + amount: [
  222 + { required: true, message: this.$t('itemReleaseManage.validate.required'), trigger: 'blur' },
  223 + { max: 12, message: this.$t('itemReleaseManage.validate.maxLength12'), trigger: 'blur' }
  224 + ],
  225 + state: [
  226 + { required: true, message: this.$t('itemReleaseManage.validate.required'), trigger: 'blur' },
  227 + { max: 12, message: this.$t('itemReleaseManage.validate.maxLength12'), trigger: 'blur' }
  228 + ],
  229 + carNum: [
  230 + { required: true, message: this.$t('itemReleaseManage.validate.required'), trigger: 'blur' },
  231 + { max: 12, message: this.$t('itemReleaseManage.validate.maxLength12'), trigger: 'blur' }
  232 + ],
  233 + remark: [
  234 + { max: 512, message: this.$t('itemReleaseManage.validate.maxLength512'), trigger: 'blur' }
  235 + ]
  236 + }
  237 + }
  238 + },
  239 + created() {
  240 + this.communityId = getCommunityId()
  241 + this.loadReleaseTypes()
  242 + },
  243 + methods: {
  244 + async loadReleaseTypes() {
  245 + try {
  246 + const params = {
  247 + page: 1,
  248 + row: 100,
  249 + communityId: this.communityId
  250 + }
  251 + const { data } = await listItemReleaseType(params)
  252 + this.releaseTypes = data
  253 + } catch (error) {
  254 + console.error('获取放行类型失败:', error)
  255 + }
  256 + },
  257 + open(data) {
  258 + this.formData = {
  259 + ...this.formData,
  260 + ...data,
  261 + communityId: this.communityId
  262 + }
  263 + this.visible = true
  264 + },
  265 + handleClose() {
  266 + this.$refs.form.resetFields()
  267 + },
  268 + handleSubmit() {
  269 + this.$refs.form.validate(async valid => {
  270 + if (valid) {
  271 + try {
  272 + await updateItemRelease(this.formData)
  273 + this.$message.success(this.$t('common.updateSuccess'))
  274 + this.$emit('success')
  275 + this.visible = false
  276 + } catch (error) {
  277 + console.error('更新物品放行失败:', error)
  278 + }
  279 + }
  280 + })
  281 + }
  282 + }
  283 +}
  284 +</script>
0 285 \ No newline at end of file
... ...
src/components/work/editItemReleaseType.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('itemReleaseTypeManage.edit.title')"
  4 + :visible.sync="visible"
  5 + width="50%"
  6 + @close="handleClose"
  7 + >
  8 + <el-form
  9 + ref="form"
  10 + :model="form"
  11 + :rules="rules"
  12 + label-width="120px"
  13 + label-position="right"
  14 + >
  15 + <el-form-item
  16 + :label="$t('itemReleaseTypeManage.form.typeName')"
  17 + prop="typeName"
  18 + >
  19 + <el-input
  20 + v-model="form.typeName"
  21 + :placeholder="$t('itemReleaseTypeManage.form.typeNamePlaceholder')"
  22 + />
  23 + </el-form-item>
  24 + <el-form-item
  25 + :label="$t('itemReleaseTypeManage.form.remark')"
  26 + prop="remark"
  27 + >
  28 + <el-input
  29 + v-model="form.remark"
  30 + type="textarea"
  31 + :rows="3"
  32 + :placeholder="$t('itemReleaseTypeManage.form.remarkPlaceholder')"
  33 + />
  34 + </el-form-item>
  35 + </el-form>
  36 +
  37 + <span slot="footer" class="dialog-footer">
  38 + <el-button @click="visible = false">
  39 + {{ $t('common.cancel') }}
  40 + </el-button>
  41 + <el-button type="primary" @click="handleSubmit">
  42 + {{ $t('common.confirm') }}
  43 + </el-button>
  44 + </span>
  45 + </el-dialog>
  46 +</template>
  47 +
  48 +<script>
  49 +import { updateItemReleaseType } from '@/api/work/itemReleaseTypeManageApi'
  50 +import { getCommunityId } from '@/api/community/communityApi'
  51 +
  52 +export default {
  53 + name: 'EditItemReleaseType',
  54 + data() {
  55 + return {
  56 + visible: false,
  57 + form: {
  58 + typeId: '',
  59 + typeName: '',
  60 + remark: '',
  61 + communityId: ''
  62 + },
  63 + rules: {
  64 + typeName: [
  65 + { required: true, message: this.$t('itemReleaseTypeManage.validate.typeNameRequired'), trigger: 'blur' },
  66 + { max: 30, message: this.$t('itemReleaseTypeManage.validate.typeNameMaxLength'), trigger: 'blur' }
  67 + ],
  68 + remark: [
  69 + { required: true, message: this.$t('itemReleaseTypeManage.validate.remarkRequired'), trigger: 'blur' },
  70 + { max: 512, message: this.$t('itemReleaseTypeManage.validate.remarkMaxLength'), trigger: 'blur' }
  71 + ],
  72 + typeId: [
  73 + { required: true, message: this.$t('itemReleaseTypeManage.validate.typeIdRequired'), trigger: 'blur' }
  74 + ]
  75 + }
  76 + }
  77 + },
  78 + methods: {
  79 + open(row) {
  80 + this.form = {
  81 + typeId: row.typeId,
  82 + typeName: row.typeName,
  83 + remark: row.remark,
  84 + communityId: getCommunityId()
  85 + }
  86 + this.visible = true
  87 + },
  88 + handleClose() {
  89 + this.$refs.form.resetFields()
  90 + },
  91 + handleSubmit() {
  92 + this.$refs.form.validate(async valid => {
  93 + if (valid) {
  94 + try {
  95 + await updateItemReleaseType(this.form)
  96 + this.$message.success(this.$t('itemReleaseTypeManage.edit.success'))
  97 + this.visible = false
  98 + this.$emit('success')
  99 + } catch (error) {
  100 + this.$message.error(this.$t('itemReleaseTypeManage.edit.error'))
  101 + }
  102 + }
  103 + })
  104 + }
  105 + }
  106 +}
  107 +</script>
0 108 \ No newline at end of file
... ...
src/components/work/orgTreeShow.vue 0 → 100644
  1 +<template>
  2 + <div class="org-tree-show-container">
  3 + <el-tree
  4 + ref="orgTree"
  5 + :data="orgs"
  6 + :props="defaultProps"
  7 + node-key="id"
  8 + default-expand-all
  9 + highlight-current
  10 + @node-click="handleNodeClick"
  11 + />
  12 + </div>
  13 +</template>
  14 +
  15 +<script>
  16 +import { listOrgTree } from '@/api/work/addItemReleaseViewApi'
  17 +import { getCommunityId } from '@/api/community/communityApi'
  18 +
  19 +export default {
  20 + name: 'OrgTreeShow',
  21 + props: {
  22 + callBackListener: {
  23 + type: String,
  24 + default: ''
  25 + }
  26 + },
  27 + data() {
  28 + return {
  29 + orgs: [],
  30 + defaultProps: {
  31 + children: 'children',
  32 + label: 'text'
  33 + },
  34 + communityId: ''
  35 + }
  36 + },
  37 + created() {
  38 + this.communityId = getCommunityId()
  39 + },
  40 + methods: {
  41 + async refreshTree() {
  42 + try {
  43 + const params = {
  44 + communityId: this.communityId
  45 + }
  46 + const res = await listOrgTree(params)
  47 + this.orgs = res.data || []
  48 + } catch (error) {
  49 + console.error('Failed to load org tree:', error)
  50 + }
  51 + },
  52 + handleNodeClick(data) {
  53 + this.$emit('switch-org', {
  54 + orgId: data.id,
  55 + orgName: data.text
  56 + })
  57 + }
  58 + }
  59 +}
  60 +</script>
  61 +
  62 +<style scoped>
  63 +.org-tree-show-container {
  64 + height: 100%;
  65 + overflow-y: auto;
  66 +}
  67 +</style>
0 68 \ No newline at end of file
... ...
src/components/work/selectStaff.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :visible.sync="visible"
  4 + :title="$t('selectStaff.title')"
  5 + width="80%"
  6 + @close="handleClose"
  7 + >
  8 + <el-row :gutter="20">
  9 + <el-col :span="12" class="border-right">
  10 + <div class="text-center mb-20">
  11 + <h4>{{ $t('selectStaff.orgInfo') }}</h4>
  12 + </div>
  13 + <div class="org-tree-container">
  14 + <OrgTreeShow ref="orgTree" @switch-org="handleSwitchOrg" />
  15 + </div>
  16 + </el-col>
  17 + <el-col :span="12">
  18 + <div class="text-center mb-20">
  19 + <h4>{{ $t('selectStaff.staffInfo') }}</h4>
  20 + </div>
  21 + <div class="staff-list-container">
  22 + <div
  23 + v-for="item in staffs"
  24 + :key="item.staffId"
  25 + class="staff-item"
  26 + :class="{ 'selected': currentStaffId === item.staffId }"
  27 + @click="selectStaff(item)"
  28 + >
  29 + <div>
  30 + <i class="el-icon-user"></i>
  31 + {{ item.name }}
  32 + </div>
  33 + <div>{{ item.tel }}</div>
  34 + </div>
  35 + </div>
  36 + </el-col>
  37 + </el-row>
  38 + <div
  39 + v-if="staff.from === 'bpmn' || staff.from === 'purchase' || staff.from === 'contract'"
  40 + slot="footer"
  41 + class="dialog-footer"
  42 + >
  43 + <el-button @click="selectFirstUser">{{ $t('selectStaff.submitter') }}</el-button>
  44 + <el-button @click="selectCustomUser">{{ $t('selectStaff.dynamicAssign') }}</el-button>
  45 + </div>
  46 + </el-dialog>
  47 +</template>
  48 +
  49 +<script>
  50 +import OrgTreeShow from './orgTreeShow'
  51 +import { queryStaffInfos } from '@/api/work/addItemReleaseViewApi'
  52 +import { getCommunityId } from '@/api/community/communityApi'
  53 +
  54 +export default {
  55 + name: 'SelectStaff',
  56 + components: {
  57 + OrgTreeShow
  58 + },
  59 + data() {
  60 + return {
  61 + visible: false,
  62 + staff: {},
  63 + staffs: [],
  64 + currentStaffId: '',
  65 + communityId: ''
  66 + }
  67 + },
  68 + created() {
  69 + this.communityId = getCommunityId()
  70 + },
  71 + methods: {
  72 + open(staff) {
  73 + this.staff = staff || {}
  74 + this.visible = true
  75 + this.$nextTick(() => {
  76 + this.$refs.orgTree.refreshTree()
  77 + })
  78 + },
  79 + handleClose() {
  80 + this.visible = false
  81 + this.staffs = []
  82 + this.currentStaffId = ''
  83 + },
  84 + async handleSwitchOrg(org) {
  85 + try {
  86 + const params = {
  87 + page: 1,
  88 + rows: 50,
  89 + row: 50,
  90 + orgId: org.orgId
  91 + }
  92 + const res = await queryStaffInfos(params)
  93 + this.staffs = res.staffs || []
  94 + if (this.staffs.length > 0) {
  95 + this.currentStaffId = this.staffs[0].staffId
  96 + }
  97 + } catch (error) {
  98 + console.error('Failed to load staffs:', error)
  99 + }
  100 + },
  101 + selectStaff(item) {
  102 + this.currentStaffId = item.staffId
  103 + this.$emit('select', {
  104 + staffId: item.userId,
  105 + staffName: item.userName,
  106 + staffTel: item.tel
  107 + })
  108 + this.visible = false
  109 + },
  110 + selectFirstUser() {
  111 + this.$emit('select', {
  112 + staffId: '${startUserId}',
  113 + staffName: this.$t('selectStaff.submitter')
  114 + })
  115 + this.visible = false
  116 + },
  117 + selectCustomUser() {
  118 + this.$emit('select', {
  119 + staffId: '${nextUserId}',
  120 + staffName: this.$t('selectStaff.dynamicAssign')
  121 + })
  122 + this.visible = false
  123 + }
  124 + }
  125 +}
  126 +</script>
  127 +
  128 +<style scoped>
  129 +.border-right {
  130 + border-right: 1px solid #ebeef5;
  131 +}
  132 +.org-tree-container,
  133 +.staff-list-container {
  134 + height: 400px;
  135 + overflow-y: auto;
  136 + padding: 10px;
  137 +}
  138 +.staff-item {
  139 + padding: 10px;
  140 + margin-bottom: 10px;
  141 + border: 1px solid #ebeef5;
  142 + border-radius: 4px;
  143 + cursor: pointer;
  144 +}
  145 +.staff-item:hover {
  146 + background-color: #f5f7fa;
  147 +}
  148 +.staff-item.selected {
  149 + background-color: #ecf5ff;
  150 + border-color: #d9ecff;
  151 +}
  152 +.text-center {
  153 + text-align: center;
  154 +}
  155 +.mb-20 {
  156 + margin-bottom: 20px;
  157 +}
  158 +</style>
0 159 \ No newline at end of file
... ...
src/components/work/viewItemReleaseRes.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('itemReleaseManage.viewItems.title')"
  4 + :visible.sync="visible"
  5 + width="50%"
  6 + >
  7 + <el-table
  8 + :data="items"
  9 + border
  10 + style="width: 100%"
  11 + v-loading="loading"
  12 + >
  13 + <el-table-column
  14 + prop="resName"
  15 + :label="$t('itemReleaseManage.viewItems.itemName')"
  16 + align="center"
  17 + />
  18 + <el-table-column
  19 + prop="amount"
  20 + :label="$t('itemReleaseManage.viewItems.amount')"
  21 + align="center"
  22 + />
  23 + </el-table>
  24 + </el-dialog>
  25 +</template>
  26 +
  27 +<script>
  28 +import { getCommunityId } from '@/api/community/communityApi'
  29 +import { listItemReleaseRes } from '@/api/work/itemReleaseManageApi'
  30 +
  31 +export default {
  32 + name: 'ViewItemReleaseRes',
  33 + data() {
  34 + return {
  35 + visible: false,
  36 + loading: false,
  37 + communityId: '',
  38 + items: [],
  39 + currentItem: {}
  40 + }
  41 + },
  42 + created() {
  43 + this.communityId = getCommunityId()
  44 + },
  45 + methods: {
  46 + open(item) {
  47 + this.currentItem = {
  48 + ...item,
  49 + communityId: this.communityId
  50 + }
  51 + this.visible = true
  52 + this.loadItems()
  53 + },
  54 + async loadItems() {
  55 + try {
  56 + this.loading = true
  57 + const params = {
  58 + page: 1,
  59 + row: 500,
  60 + communityId: this.communityId,
  61 + irId: this.currentItem.irId
  62 + }
  63 + const { data } = await listItemReleaseRes(params)
  64 + this.items = data
  65 + } catch (error) {
  66 + console.error('获取放行物品失败:', error)
  67 + } finally {
  68 + this.loading = false
  69 + }
  70 + }
  71 + }
  72 +}
  73 +</script>
0 74 \ No newline at end of file
... ...
src/i18n/communityI18n.js
... ... @@ -2,17 +2,26 @@ import { messages as roomStructureMessages } from &#39;../views/room/roomStructureLa
2 2 import { messages as carStructureMessages } from '../views/car/carStructureLang'
3 3 import { messages as propertyRightRegistrationManageMessages } from '../views/room/propertyRightRegistrationManageLang'
4 4 import { messages as listPropertyRightRegistrationDetailMessages } from '../views/room/listPropertyRightRegistrationDetailLang'
  5 +import { messages as communityPublicityManageMessages } from '../views/community/communityPublicityManageLang'
  6 +import { messages as addCommunityPublicityMessages } from '../views/community/addCommunityPublicityLang'
  7 +import { messages as editCommunityPublicityMessages } from '../views/community/editCommunityPublicityLang'
5 8 export const messages = {
6 9 en: {
7 10 ...roomStructureMessages.en,
8 11 ...carStructureMessages.en,
9 12 ...propertyRightRegistrationManageMessages.en,
10 13 ...listPropertyRightRegistrationDetailMessages.en,
  14 + ...communityPublicityManageMessages.en,
  15 + ...addCommunityPublicityMessages.en,
  16 + ...editCommunityPublicityMessages.en,
11 17 },
12 18 zh: {
13 19 ...roomStructureMessages.zh,
14 20 ...carStructureMessages.zh,
15 21 ...propertyRightRegistrationManageMessages.zh,
16 22 ...listPropertyRightRegistrationDetailMessages.zh,
  23 + ...communityPublicityManageMessages.zh,
  24 + ...addCommunityPublicityMessages.zh,
  25 + ...editCommunityPublicityMessages.zh,
17 26 }
18 27 }
19 28 \ No newline at end of file
... ...
src/i18n/index.js
... ... @@ -145,6 +145,7 @@ import { messages as scmI18n } from &#39;./scmI18n&#39;
145 145 import { messages as userI18n } from './userI18n'
146 146 import { messages as systemI18n } from './systemI18n'
147 147 import { messages as communityI18n } from './communityI18n'
  148 +import { messages as workI18n } from './workI18n'
148 149  
149 150 Vue.use(VueI18n)
150 151  
... ... @@ -288,6 +289,7 @@ const messages = {
288 289 ...userI18n.en,
289 290 ...systemI18n.en,
290 291 ...communityI18n.en,
  292 + ...workI18n.en,
291 293 },
292 294 zh: {
293 295 ...loginMessages.zh,
... ... @@ -425,6 +427,7 @@ const messages = {
425 427 ...userI18n.zh,
426 428 ...systemI18n.zh,
427 429 ...communityI18n.zh,
  430 + ...workI18n.zh,
428 431 }
429 432 }
430 433  
... ...
src/i18n/workI18n.js 0 → 100644
  1 +import { messages as itemReleaseTypeManageMessages } from '../views/work/itemReleaseTypeManageLang'
  2 +import { messages as itemReleaseManageMessages } from '../views/work/itemReleaseManageLang'
  3 +
  4 +import { messages as addItemReleaseViewMessages } from '../views/work/addItemReleaseViewLang'
  5 +export const messages = {
  6 + zh: {
  7 + ...itemReleaseTypeManageMessages.zh,
  8 + ...itemReleaseManageMessages.zh,
  9 + ...addItemReleaseViewMessages.zh,
  10 + },
  11 + en: {
  12 + ...itemReleaseTypeManageMessages.en,
  13 + ...itemReleaseManageMessages.en,
  14 + ...addItemReleaseViewMessages.en,
  15 + }
  16 +}
0 17 \ No newline at end of file
... ...
src/router/communityRouter.js
... ... @@ -19,4 +19,19 @@ export default [
19 19 name: '/views/room/listPropertyRightRegistrationDetail',
20 20 component: () => import('@/views/room/listPropertyRightRegistrationDetailList.vue')
21 21 },
  22 + {
  23 + path: '/pages/community/communityPublicityManage',
  24 + name: '/pages/community/communityPublicityManage',
  25 + component: () => import('@/views/community/communityPublicityManageList.vue')
  26 + },
  27 + {
  28 + path: '/views/community/addCommunityPublicity',
  29 + name: '/views/community/addCommunityPublicity',
  30 + component: () => import('@/views/community/addCommunityPublicityList.vue')
  31 + },
  32 + {
  33 + path: '/views/community/editCommunityPublicity',
  34 + name: '/views/community/editCommunityPublicity',
  35 + component: () => import('@/views/community/editCommunityPublicityList.vue')
  36 + },
22 37 ]
23 38 \ No newline at end of file
... ...
src/router/index.js
... ... @@ -15,6 +15,7 @@ import scmRouter from &#39;./scmRouter&#39;
15 15 import userRouter from './userRouter'
16 16 import systemRouter from './systemRouter'
17 17 import communityRouter from './communityRouter'
  18 +import workRouter from './workRouter'
18 19  
19 20 Vue.use(VueRouter)
20 21  
... ... @@ -638,6 +639,7 @@ const routes = [
638 639 ...userRouter,
639 640 ...systemRouter,
640 641 ...communityRouter,
  642 + ...workRouter,
641 643 // 其他子路由可以在这里添加
642 644 ]
643 645 },
... ...
src/router/workRouter.js 0 → 100644
  1 +export default [
  2 + {
  3 + path: '/pages/property/itemReleaseTypeManage',
  4 + name: '/pages/property/itemReleaseTypeManage',
  5 + component: () => import('@/views/work/itemReleaseTypeManageList.vue')
  6 + },
  7 + {
  8 + path: '/pages/property/itemReleaseManage',
  9 + name: '/pages/property/itemReleaseManage',
  10 + component: () => import('@/views/work/itemReleaseManageList.vue')
  11 + },
  12 + {
  13 + path: '/views/work/addItemReleaseView',
  14 + name: '/views/work/addItemReleaseView',
  15 + component: () => import('@/views/work/addItemReleaseViewList.vue')
  16 + },
  17 +]
0 18 \ No newline at end of file
... ...
src/views/community/addCommunityPublicityLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + addCommunityPublicity: {
  4 + title: 'Add Community Publicity',
  5 + pubTitle: 'Publicity Title',
  6 + pubType: 'Publicity Type',
  7 + headerPhoto: 'Header Photo',
  8 + activityContent: 'Activity Content',
  9 + back: 'Back',
  10 + submit: 'Submit',
  11 + requiredTitle: 'Required, please fill in the publicity title',
  12 + requiredType: 'Required, please select publicity type',
  13 + requiredContent: 'Required, please enter announcement content'
  14 + }
  15 + },
  16 + zh: {
  17 + addCommunityPublicity: {
  18 + title: '添加社区公示',
  19 + pubTitle: '公示标题',
  20 + pubType: '公示类型',
  21 + headerPhoto: '头部照片',
  22 + activityContent: '活动内容',
  23 + back: '返回',
  24 + submit: '提交',
  25 + requiredTitle: '必填,请填写公示标题',
  26 + requiredType: '必填,请选择公示类型',
  27 + requiredContent: '必填,请输入公告内容'
  28 + }
  29 + }
  30 +}
0 31 \ No newline at end of file
... ...
src/views/community/addCommunityPublicityList.vue 0 → 100644
  1 +<template>
  2 + <el-card class="add-publicity-container">
  3 + <div slot="header">
  4 + <span>{{ $t('addCommunityPublicity.title') }}</span>
  5 + <el-button
  6 + style="float: right; padding: 3px 0"
  7 + type="text"
  8 + @click="goBack">
  9 + <i class="el-icon-close"></i>{{ $t('addCommunityPublicity.back') }}
  10 + </el-button>
  11 + </div>
  12 +
  13 + <el-form ref="form" :model="formData" label-width="120px">
  14 + <el-row :gutter="20">
  15 + <el-col :span="12">
  16 + <el-form-item
  17 + :label="$t('addCommunityPublicity.pubTitle')"
  18 + prop="title"
  19 + :rules="[{ required: true, message: $t('addCommunityPublicity.requiredTitle'), trigger: 'blur' }]">
  20 + <el-input
  21 + v-model="formData.title"
  22 + :placeholder="$t('addCommunityPublicity.requiredTitle')"
  23 + clearable>
  24 + </el-input>
  25 + </el-form-item>
  26 + </el-col>
  27 + <el-col :span="12">
  28 + <el-form-item
  29 + :label="$t('addCommunityPublicity.pubType')"
  30 + prop="pubType"
  31 + :rules="[{ required: true, message: $t('addCommunityPublicity.requiredType'), trigger: 'change' }]">
  32 + <el-select
  33 + v-model="formData.pubType"
  34 + :placeholder="$t('addCommunityPublicity.requiredType')"
  35 + style="width: 100%">
  36 + <el-option
  37 + v-for="item in pubTypes"
  38 + :key="item.statusCd"
  39 + :label="item.name"
  40 + :value="item.statusCd">
  41 + </el-option>
  42 + </el-select>
  43 + </el-form-item>
  44 + </el-col>
  45 + </el-row>
  46 +
  47 + <el-form-item
  48 + :label="$t('addCommunityPublicity.headerPhoto')"
  49 + prop="headerImg"
  50 + :rules="[{ required: true, message: $t('addCommunityPublicity.requiredHeaderPhoto'), trigger: 'change' }]">
  51 + <upload-image-url
  52 + ref="uploadImage"
  53 + :image-count="1"
  54 + @notifyUploadCoverImage="handleImageUpload">
  55 + </upload-image-url>
  56 + </el-form-item>
  57 +
  58 + <el-form-item
  59 + :label="$t('addCommunityPublicity.activityContent')"
  60 + prop="context"
  61 + :rules="[{ required: true, message: $t('addCommunityPublicity.requiredContent'), trigger: 'blur' }]">
  62 + <rich-text-editor
  63 + v-model="formData.context"
  64 + :height="300"
  65 + :placeholder="$t('addCommunityPublicity.requiredContent')">
  66 + </rich-text-editor>
  67 + </el-form-item>
  68 +
  69 + <el-form-item class="text-right">
  70 + <el-button @click="goBack">{{ $t('addCommunityPublicity.back') }}</el-button>
  71 + <el-button type="primary" @click="submitForm">{{ $t('addCommunityPublicity.submit') }}</el-button>
  72 + </el-form-item>
  73 + </el-form>
  74 + </el-card>
  75 +</template>
  76 +
  77 +<script>
  78 +import UploadImageUrl from '@/components/upload/UploadImageUrl'
  79 +import { saveCommunityPublicity } from '@/api/community/addCommunityPublicityApi'
  80 +import { getCommunityId ,getDict} from '@/api/community/communityApi'
  81 +import richTextEditor from '@/components/editor/RichTextEditor'
  82 +
  83 +export default {
  84 + name: 'AddCommunityPublicity',
  85 + components: {
  86 + UploadImageUrl,
  87 + richTextEditor
  88 + },
  89 + data() {
  90 + return {
  91 + formData: {
  92 + title: '',
  93 + pubType: '',
  94 + headerImg: '',
  95 + context: ''
  96 + },
  97 + pubTypes: []
  98 + }
  99 + },
  100 + created() {
  101 + this.getPublicityTypes()
  102 + },
  103 + methods: {
  104 + async getPublicityTypes() {
  105 + try {
  106 + const data = await getDict('community_publicity', 'pub_type')
  107 + this.pubTypes = data
  108 + } catch (error) {
  109 + console.error('Failed to get publicity types:', error)
  110 + this.$message.error(this.$t('addCommunityPublicity.fetchTypesFailed'))
  111 + }
  112 + },
  113 + handleImageUpload(images) {
  114 + if (images.length > 0) {
  115 + this.formData.headerImg = images[0]|| images[0]
  116 + } else {
  117 + this.formData.headerImg = ''
  118 + }
  119 + },
  120 + submitForm() {
  121 + this.$refs.form.validate(valid => {
  122 + if (valid) {
  123 + this.savePublicity()
  124 + } else {
  125 + return false
  126 + }
  127 + })
  128 + },
  129 + async savePublicity() {
  130 + try {
  131 + this.formData.communityId = getCommunityId()
  132 + const response = await saveCommunityPublicity(this.formData)
  133 + if (response.code === 0) {
  134 + this.$message.success(this.$t('addCommunityPublicity.saveSuccess'))
  135 + this.goBack()
  136 + } else {
  137 + this.$message.error(response.msg || this.$t('addCommunityPublicity.saveFailed'))
  138 + }
  139 + } catch (error) {
  140 + console.error('Save publicity error:', error)
  141 + this.$message.error(this.$t('addCommunityPublicity.saveFailed'))
  142 + }
  143 + },
  144 + goBack() {
  145 + this.$router.go(-1)
  146 + }
  147 + }
  148 +}
  149 +</script>
  150 +
  151 +<style scoped>
  152 +.add-publicity-container {
  153 + margin: 20px;
  154 +}
  155 +.text-right {
  156 + text-align: right;
  157 +}
  158 +</style>
0 159 \ No newline at end of file
... ...
src/views/community/communityPublicityManageLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + communityPublicityManage: {
  4 + searchTitle: 'Search Conditions',
  5 + titlePlaceholder: 'Please enter publicity title',
  6 + tableTitle: 'Community Publicity List',
  7 + headerImg: 'Header Image',
  8 + title: 'Publicity Title',
  9 + pubType: 'Publicity Type',
  10 + createTime: 'Publicity Time',
  11 + publisher: 'Publisher',
  12 + deleteTitle: 'Confirm Delete',
  13 + deleteConfirm: 'Are you sure to delete this community publicity?',
  14 + deleteSuccess: 'Delete successfully',
  15 + deleteError: 'Delete failed'
  16 + }
  17 + },
  18 + zh: {
  19 + communityPublicityManage: {
  20 + searchTitle: '查询条件',
  21 + titlePlaceholder: '请输入公示标题',
  22 + tableTitle: '小区公示列表',
  23 + headerImg: '头部照片',
  24 + title: '公示标题',
  25 + pubType: '公示类型',
  26 + createTime: '公示时间',
  27 + publisher: '发布人',
  28 + deleteTitle: '确认删除',
  29 + deleteConfirm: '确定要删除这条小区公示吗?',
  30 + deleteSuccess: '删除成功',
  31 + deleteError: '删除失败'
  32 + }
  33 + }
  34 +}
0 35 \ No newline at end of file
... ...
src/views/community/communityPublicityManageList.vue 0 → 100644
  1 +<template>
  2 + <div class="community-publicity-manage-container">
  3 + <el-row :gutter="20">
  4 + <el-col :span="4">
  5 + <el-card class="tree-card">
  6 + <ul class="pub-type-list">
  7 + <li v-for="(item, index) in pubTypes" :key="index" class="pub-type-item"
  8 + :class="{ 'active': conditions.pubType === item.statusCd }" @click="handlePubTypeChange(item)">
  9 + {{ item.name }}
  10 + </li>
  11 + </ul>
  12 + </el-card>
  13 + </el-col>
  14 + <el-col :span="20">
  15 + <el-card class="search-card">
  16 + <div slot="header" class="flex justify-between">
  17 + <span>{{ $t('communityPublicityManage.searchTitle') }}</span>
  18 + </div>
  19 + <el-row :gutter="20">
  20 + <el-col :span="8">
  21 + <el-input v-model="conditions.title" :placeholder="$t('communityPublicityManage.titlePlaceholder')"
  22 + clearable />
  23 + </el-col>
  24 + <el-col :span="8">
  25 + <el-button type="primary" @click="handleSearch">
  26 + {{ $t('common.search') }}
  27 + </el-button>
  28 + <el-button @click="handleReset">
  29 + {{ $t('common.reset') }}
  30 + </el-button>
  31 + </el-col>
  32 + </el-row>
  33 + </el-card>
  34 +
  35 + <el-card class="table-card">
  36 + <div slot="header" class="flex justify-between">
  37 + <span>{{ $t('communityPublicityManage.tableTitle') }}</span>
  38 + <el-button type="primary" size="small" @click="handleAdd">
  39 + {{ $t('common.add') }}
  40 + </el-button>
  41 + </div>
  42 + <el-table :data="tableData" border style="width: 100%" v-loading="loading">
  43 + <el-table-column prop="headerImg" :label="$t('communityPublicityManage.headerImg')" width="120"
  44 + align="center">
  45 + <template slot-scope="scope">
  46 + <el-image style="width: 60px; height: 60px; cursor: pointer;"
  47 + :src="scope.row.headerImg || '/img/noPhoto.jpg'"
  48 + :preview-src-list="[scope.row.headerImg || '/img/noPhoto.jpg']" fit="cover" class="border-radius" />
  49 + </template>
  50 + </el-table-column>
  51 + <el-table-column prop="title" :label="$t('communityPublicityManage.title')" align="center" />
  52 + <el-table-column prop="pubTypeName" :label="$t('communityPublicityManage.pubType')" align="center" />
  53 + <el-table-column prop="createTime" :label="$t('communityPublicityManage.createTime')" align="center" />
  54 + <el-table-column prop="createUserName" :label="$t('communityPublicityManage.publisher')" align="center" />
  55 + <el-table-column :label="$t('common.operation')" align="center" width="200">
  56 + <template slot-scope="scope">
  57 + <el-button size="mini" type="primary" @click="handleEdit(scope.row)">
  58 + {{ $t('common.edit') }}
  59 + </el-button>
  60 + <el-button size="mini" type="danger" @click="handleDelete(scope.row)">
  61 + {{ $t('common.delete') }}
  62 + </el-button>
  63 + </template>
  64 + </el-table-column>
  65 + </el-table>
  66 + <el-pagination :current-page="pagination.current" :page-sizes="[10, 20, 30, 50]" :page-size="pagination.size"
  67 + :total="pagination.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
  68 + @current-change="handleCurrentChange" style="margin-top: 20px;" />
  69 + </el-card>
  70 + </el-col>
  71 + </el-row>
  72 +
  73 + <view-image ref="viewImage" />
  74 + <delete-community-publicity ref="deleteDialog" @success="fetchData" />
  75 + </div>
  76 +</template>
  77 +
  78 +<script>
  79 +import { getCommunityPublicityList } from '@/api/community/communityPublicityManageApi'
  80 +import { getDict } from '@/api/community/communityApi'
  81 +import ViewImage from '@/components/system/viewImage'
  82 +import DeleteCommunityPublicity from '@/components/community/deleteCommunityPublicity'
  83 +import { getCommunityId } from '@/api/community/communityApi'
  84 +
  85 +export default {
  86 + name: 'CommunityPublicityManageList',
  87 + components: {
  88 + ViewImage,
  89 + DeleteCommunityPublicity
  90 + },
  91 + data() {
  92 + return {
  93 + loading: false,
  94 + pubTypes: [],
  95 + tableData: [],
  96 + conditions: {
  97 + pubType: '',
  98 + title: '',
  99 + communityId: ''
  100 + },
  101 + pagination: {
  102 + current: 1,
  103 + size: 10,
  104 + total: 0
  105 + }
  106 + }
  107 + },
  108 + created() {
  109 + this.conditions.communityId = getCommunityId()
  110 + this.initData()
  111 + },
  112 + methods: {
  113 + async initData() {
  114 + try {
  115 + this.loading = true
  116 + await this.getPubTypes()
  117 + if (this.pubTypes.length > 0) {
  118 + this.conditions.pubType = this.pubTypes[0].statusCd
  119 + }
  120 + await this.fetchData()
  121 + } catch (error) {
  122 + console.error('初始化数据失败:', error)
  123 + } finally {
  124 + this.loading = false
  125 + }
  126 + },
  127 + async getPubTypes() {
  128 + try {
  129 + const data = await getDict('community_publicity', 'pub_type')
  130 + this.pubTypes = data
  131 + } catch (error) {
  132 + console.error('获取公示类型失败:', error)
  133 + }
  134 + },
  135 + async fetchData() {
  136 + try {
  137 + this.loading = true
  138 + const params = {
  139 + page: this.pagination.current,
  140 + row: this.pagination.size,
  141 + ...this.conditions
  142 + }
  143 + const { data, total } = await getCommunityPublicityList(params)
  144 + this.tableData = data
  145 + this.pagination.total = total
  146 + } catch (error) {
  147 + console.error('获取公示列表失败:', error)
  148 + } finally {
  149 + this.loading = false
  150 + }
  151 + },
  152 + handlePubTypeChange(item) {
  153 + this.conditions.pubType = item.statusCd
  154 + this.pagination.current = 1
  155 + this.fetchData()
  156 + },
  157 + handleSearch() {
  158 + this.pagination.current = 1
  159 + this.fetchData()
  160 + },
  161 + handleReset() {
  162 + this.conditions.title = ''
  163 + this.pagination.current = 1
  164 + this.fetchData()
  165 + },
  166 + handleAdd() {
  167 + this.$router.push('/views/community/addCommunityPublicity')
  168 + },
  169 + handleEdit(row) {
  170 + this.$router.push(`/views/community/editCommunityPublicity?pubId=${row.pubId}`)
  171 + },
  172 + handleDelete(row) {
  173 + this.$refs.deleteDialog.open(row)
  174 + },
  175 + handleSizeChange(val) {
  176 + this.pagination.size = val
  177 + this.fetchData()
  178 + },
  179 + handleCurrentChange(val) {
  180 + this.pagination.current = val
  181 + this.fetchData()
  182 + }
  183 + }
  184 +}
  185 +</script>
  186 +
  187 +<style lang="scss" scoped>
  188 +.community-publicity-manage-container {
  189 + padding: 20px;
  190 +
  191 + .tree-card {
  192 + height: 100%;
  193 +
  194 + .pub-type-list {
  195 + list-style: none;
  196 + padding: 0;
  197 + margin: 0;
  198 +
  199 + .pub-type-item {
  200 + padding: 10px 15px;
  201 + cursor: pointer;
  202 + border-radius: 4px;
  203 + margin-bottom: 5px;
  204 + transition: all 0.3s;
  205 +
  206 + &:hover {
  207 + background-color: #f5f7fa;
  208 + }
  209 +
  210 + &.active {
  211 + background-color: #409eff;
  212 + color: white;
  213 + }
  214 + }
  215 + }
  216 + }
  217 +
  218 + .search-card {
  219 + margin-bottom: 20px;
  220 + }
  221 +
  222 + .border-radius {
  223 + border-radius: 4px;
  224 + }
  225 +}
  226 +</style>
0 227 \ No newline at end of file
... ...
src/views/community/editCommunityPublicityLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + editCommunityPublicity: {
  4 + title: 'Edit Publicity',
  5 + publicityTitle: 'Publicity Title',
  6 + publicityTitlePlaceholder: 'Required, please enter publicity title',
  7 + publicityType: 'Publicity Type',
  8 + publicityTypePlaceholder: 'Required, please select publicity type',
  9 + headerImage: 'Header Image',
  10 + activityContent: 'Activity Content',
  11 + activityContentPlaceholder: 'Required, please enter activity content',
  12 + validate: {
  13 + titleRequired: 'Publicity title is required',
  14 + typeRequired: 'Publicity type is required',
  15 + imageRequired: 'Header image is required',
  16 + contentRequired: 'Activity content is required'
  17 + },
  18 + message: {
  19 + updateSuccess: 'Update publicity successfully',
  20 + updateFailed: 'Update publicity failed'
  21 + }
  22 + },
  23 + uploadImage: {
  24 + message: {
  25 + sizeLimit: 'Image size cannot exceed 2MB',
  26 + uploadFailed: 'Upload image failed'
  27 + }
  28 + }
  29 + },
  30 + zh: {
  31 + editCommunityPublicity: {
  32 + title: '修改公示',
  33 + publicityTitle: '公示标题',
  34 + publicityTitlePlaceholder: '必填,请填写公示标题',
  35 + publicityType: '公示类型',
  36 + publicityTypePlaceholder: '必填,请选择公示类型',
  37 + headerImage: '头部照片',
  38 + activityContent: '活动内容',
  39 + activityContentPlaceholder: '必填,请输入活动内容',
  40 + validate: {
  41 + titleRequired: '公示标题不能为空',
  42 + typeRequired: '公示类型不能为空',
  43 + imageRequired: '头部照片不能为空',
  44 + contentRequired: '活动内容不能为空'
  45 + },
  46 + message: {
  47 + updateSuccess: '修改公示成功',
  48 + updateFailed: '修改公示失败'
  49 + }
  50 + },
  51 + uploadImage: {
  52 + message: {
  53 + sizeLimit: '图片大小不能超过2MB',
  54 + uploadFailed: '图片上传失败'
  55 + }
  56 + }
  57 + }
  58 +}
0 59 \ No newline at end of file
... ...
src/views/community/editCommunityPublicityList.vue 0 → 100644
  1 +<template>
  2 + <div class="edit-community-publicity-container">
  3 + <el-card>
  4 + <div slot="header" class="clearfix">
  5 + <span>{{ $t('editCommunityPublicity.title') }}</span>
  6 + <el-button
  7 + style="float: right; padding: 3px 0"
  8 + type="text"
  9 + @click="_goBack"
  10 + >
  11 + <i class="el-icon-close"></i>{{ $t('common.back') }}
  12 + </el-button>
  13 + </div>
  14 +
  15 + <el-form ref="form" :model="editCommunityPublicityInfo" label-width="120px" label-position="right">
  16 + <el-row :gutter="20">
  17 + <el-col :span="12">
  18 + <el-form-item
  19 + :label="$t('editCommunityPublicity.publicityTitle')"
  20 + prop="title"
  21 + :rules="[{ required: true, message: $t('editCommunityPublicity.validate.titleRequired'), trigger: 'blur' }]">
  22 + <el-input
  23 + v-model="editCommunityPublicityInfo.title"
  24 + :placeholder="$t('editCommunityPublicity.publicityTitlePlaceholder')"
  25 + clearable>
  26 + </el-input>
  27 + </el-form-item>
  28 + </el-col>
  29 + <el-col :span="12">
  30 + <el-form-item
  31 + :label="$t('editCommunityPublicity.publicityType')"
  32 + prop="pubType"
  33 + :rules="[{ required: true, message: $t('editCommunityPublicity.validate.typeRequired'), trigger: 'change' }]">
  34 + <el-select
  35 + v-model="editCommunityPublicityInfo.pubType"
  36 + style="width:100%"
  37 + :placeholder="$t('editCommunityPublicity.publicityTypePlaceholder')">
  38 + <el-option
  39 + v-for="item in editCommunityPublicityInfo.pubTypes"
  40 + :key="item.statusCd"
  41 + :label="item.name"
  42 + :value="item.statusCd">
  43 + </el-option>
  44 + </el-select>
  45 + </el-form-item>
  46 + </el-col>
  47 + </el-row>
  48 +
  49 + <el-form-item
  50 + :label="$t('editCommunityPublicity.headerImage')"
  51 + prop="headerImg"
  52 + :rules="[{ required: true, message: $t('editCommunityPublicity.validate.imageRequired'), trigger: 'change' }]">
  53 + <upload-image-url
  54 + ref="uploadImage"
  55 + :image-count="1"
  56 + @notifyUploadCoverImage="handleUploadImage">
  57 + </upload-image-url>
  58 + </el-form-item>
  59 +
  60 + <el-form-item
  61 + :label="$t('editCommunityPublicity.activityContent')"
  62 + prop="context"
  63 + :rules="[{ required: true, message: $t('editCommunityPublicity.validate.contentRequired'), trigger: 'blur' }]">
  64 + <rich-text-editor
  65 + v-model="editCommunityPublicityInfo.context"
  66 + ref="richTextEditor"
  67 + :height="300"
  68 + :placeholder="$t('editCommunityPublicity.activityContentPlaceholder')">
  69 + </rich-text-editor>
  70 + </el-form-item>
  71 +
  72 + <el-form-item class="text-right">
  73 + <el-button @click="_goBack">{{ $t('common.back') }}</el-button>
  74 + <el-button type="primary" @click="saveCommunityPublicityInfo">
  75 + <i class="el-icon-check"></i>{{ $t('common.submit') }}
  76 + </el-button>
  77 + </el-form-item>
  78 + </el-form>
  79 + </el-card>
  80 + </div>
  81 +</template>
  82 +
  83 +<script>
  84 +import UploadImageUrl from '@/components/upload/UploadImageUrl'
  85 +import richTextEditor from '@/components/editor/RichTextEditor'
  86 +import { updateCommunityPublicity, listCommunityPublicity } from '@/api/community/editCommunityPublicityApi'
  87 +import { getDict } from '@/api/community/communityApi'
  88 +import { getCommunityId } from '@/api/community/communityApi'
  89 +
  90 +export default {
  91 + name: 'EditCommunityPublicity',
  92 + components: {
  93 + UploadImageUrl,
  94 + richTextEditor
  95 + },
  96 + data() {
  97 + return {
  98 + editCommunityPublicityInfo: {
  99 + pubId: '',
  100 + title: '',
  101 + pubType: '',
  102 + pubTypes: [],
  103 + headerImg: '',
  104 + context: ''
  105 + }
  106 + }
  107 + },
  108 + created() {
  109 + this._initData()
  110 + },
  111 + methods: {
  112 + async _initData() {
  113 + this.editCommunityPublicityInfo.pubId = this.$route.query.pubId
  114 + this.communityId = await getCommunityId()
  115 + await this._loadCommunityPublicity()
  116 + await this._loadDictData()
  117 + },
  118 + async _loadDictData() {
  119 + try {
  120 + const data = await getDict('community_publicity', 'pub_type')
  121 + this.editCommunityPublicityInfo.pubTypes = data
  122 + } catch (error) {
  123 + console.error('获取字典数据失败:', error)
  124 + }
  125 + },
  126 + async _loadCommunityPublicity() {
  127 + try {
  128 + const params = {
  129 + page: 1,
  130 + row: 1,
  131 + communityId: this.communityId,
  132 + pubId: this.editCommunityPublicityInfo.pubId
  133 + }
  134 + const { data } = await listCommunityPublicity(params)
  135 + if (data && data.length > 0) {
  136 + Object.assign(this.editCommunityPublicityInfo, data[0])
  137 + // 设置图片,如果有的话
  138 + if (this.editCommunityPublicityInfo.headerImg) {
  139 + this.$refs.uploadImage.setImages([this.editCommunityPublicityInfo.headerImg])
  140 + }
  141 + this.$refs.richTextEditor.setContent(this.editCommunityPublicityInfo.context)
  142 + }
  143 + } catch (error) {
  144 + console.error('加载公示信息失败:', error)
  145 + }
  146 + },
  147 + handleUploadImage(images) {
  148 + if (images.length > 0) {
  149 + this.editCommunityPublicityInfo.headerImg = images[0]
  150 + } else {
  151 + this.editCommunityPublicityInfo.headerImg = ''
  152 + }
  153 + },
  154 + async saveCommunityPublicityInfo() {
  155 + this.$refs.form.validate(valid => {
  156 + if (valid) {
  157 + this._saveData()
  158 + } else {
  159 + return false
  160 + }
  161 + })
  162 + },
  163 + async _saveData() {
  164 + try {
  165 + const data = {
  166 + ...this.editCommunityPublicityInfo,
  167 + communityId: this.communityId
  168 + }
  169 + const res = await updateCommunityPublicity(data)
  170 + if (res.code === 0) {
  171 + this.$message.success(this.$t('editCommunityPublicity.message.updateSuccess'))
  172 + this._goBack()
  173 + } else {
  174 + this.$message.error(res.msg || this.$t('editCommunityPublicity.message.updateFailed'))
  175 + }
  176 + } catch (error) {
  177 + console.error('保存公示信息失败:', error)
  178 + this.$message.error(this.$t('editCommunityPublicity.message.updateFailed'))
  179 + }
  180 + },
  181 + _goBack() {
  182 + this.$router.go(-1)
  183 + }
  184 + }
  185 +}
  186 +</script>
  187 +
  188 +<style lang="scss" scoped>
  189 +.edit-community-publicity-container {
  190 + padding: 20px;
  191 +
  192 + .el-card {
  193 + width: 100%;
  194 + }
  195 +
  196 + .el-form-item {
  197 + margin-bottom: 22px;
  198 + }
  199 +
  200 + .text-right {
  201 + text-align: right;
  202 + }
  203 +}
  204 +</style>
0 205 \ No newline at end of file
... ...
src/views/work/addItemReleaseViewLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + addItemReleaseView: {
  4 + title: 'Apply for Release',
  5 + releaseType: 'Release Type',
  6 + requiredSelectReleaseType: 'Required, please select release type',
  7 + applyCompany: 'Application Company',
  8 + requiredApplyCompany: 'Required, please fill in application company',
  9 + applyPerson: 'Applicant',
  10 + requiredApplyPerson: 'Required, please fill in applicant',
  11 + idCard: 'ID Card',
  12 + requiredIdCard: 'Required, please fill in ID card',
  13 + phone: 'Phone',
  14 + requiredPhone: 'Required, please fill in phone',
  15 + passTime: 'Pass Time',
  16 + requiredPassTime: 'Required, please fill in pass time',
  17 + carNum: 'License Plate',
  18 + optionalCarNum: 'Optional, please fill in license plate',
  19 + remark: 'Remark',
  20 + optionalRemark: 'Optional, please fill in remark',
  21 + releaseItems: 'Release Items',
  22 + addItem: 'Add Item',
  23 + itemName: 'Item Name',
  24 + requiredItemName: 'Required, please fill in item name',
  25 + itemAmount: 'Item Amount',
  26 + requiredItemAmount: 'Required, please fill in amount',
  27 + approverInfo: 'Approver Information',
  28 + approver: 'Approver',
  29 + requiredApprover: 'Required, please select approver',
  30 + validate: {
  31 + releaseType: 'Release type cannot be empty',
  32 + applyCompany: 'Application company cannot be empty',
  33 + applyPerson: 'Applicant cannot be empty',
  34 + idCard: 'ID card cannot be empty',
  35 + phone: 'Phone cannot be empty',
  36 + passTime: 'Pass time cannot be empty',
  37 + itemsRequired: 'At least one item is required',
  38 + itemInfoRequired: 'Item name and amount are required',
  39 + approverRequired: 'Approver is required'
  40 + }
  41 + },
  42 + selectStaff: {
  43 + title: 'Select Staff',
  44 + orgInfo: 'Organization Information',
  45 + staffInfo: 'Staff Information',
  46 + submitter: 'Submitter',
  47 + dynamicAssign: 'Dynamic Assignment'
  48 + }
  49 + },
  50 + zh: {
  51 + addItemReleaseView: {
  52 + title: '申请放行',
  53 + releaseType: '放行类型',
  54 + requiredSelectReleaseType: '必填,请选择放行类型',
  55 + applyCompany: '申请单位',
  56 + requiredApplyCompany: '必填,请填写申请单位',
  57 + applyPerson: '申请人',
  58 + requiredApplyPerson: '必填,请填写申请人',
  59 + idCard: '身份证',
  60 + requiredIdCard: '必填,请填写身份证',
  61 + phone: '手机号',
  62 + requiredPhone: '必填,请填写手机号',
  63 + passTime: '通行时间',
  64 + requiredPassTime: '必填,请填写通行时间',
  65 + carNum: '车牌号',
  66 + optionalCarNum: '选填,请填写车牌号',
  67 + remark: '备注',
  68 + optionalRemark: '选填,请填写备注',
  69 + releaseItems: '放行物品',
  70 + addItem: '添加物品',
  71 + itemName: '物品名称',
  72 + requiredItemName: '必填,请填写物品名称',
  73 + itemAmount: '物品数量',
  74 + requiredItemAmount: '必填,请填写数量',
  75 + approverInfo: '审批人信息',
  76 + approver: '审批人',
  77 + requiredApprover: '必填,请选择审批人',
  78 + validate: {
  79 + releaseType: '放行类型不能为空',
  80 + applyCompany: '申请单位不能为空',
  81 + applyPerson: '申请人不能为空',
  82 + idCard: '身份证不能为空',
  83 + phone: '手机号不能为空',
  84 + passTime: '通行时间不能为空',
  85 + itemsRequired: '至少需要一个放行物品',
  86 + itemInfoRequired: '物品名称和数量不能为空',
  87 + approverRequired: '审批人不能为空'
  88 + }
  89 + },
  90 + selectStaff: {
  91 + title: '选择员工',
  92 + orgInfo: '组织信息',
  93 + staffInfo: '员工信息',
  94 + submitter: '提交者',
  95 + dynamicAssign: '动态指定'
  96 + }
  97 + }
  98 +}
0 99 \ No newline at end of file
... ...
src/views/work/addItemReleaseViewList.vue 0 → 100644
  1 +<template>
  2 + <div class="add-item-release-view-container">
  3 + <el-card class="box-card">
  4 + <div slot="header" class="flex justify-between">
  5 + <span>{{ $t('addItemReleaseView.title') }}</span>
  6 + <el-button type="primary" class="float-right" icon="el-icon-close" @click="goBack">
  7 + {{ $t('common.back') }}
  8 + </el-button>
  9 + </div>
  10 +
  11 + <el-row :gutter="20">
  12 + <el-col :span="24">
  13 +
  14 + <el-form label-width="120px">
  15 + <el-row :gutter="20">
  16 + <el-col :span="12">
  17 + <el-form-item :label="$t('addItemReleaseView.releaseType')">
  18 + <el-select v-model="form.typeId" style="width:100%" @change="changeItemReleaseType">
  19 + <el-option disabled :value="''" :label="$t('addItemReleaseView.requiredSelectReleaseType')" />
  20 + <el-option v-for="item in form.itemReleaseTypes" :key="item.typeId" :label="item.typeName"
  21 + :value="item.typeId" :disabled="item.state !== 'C'" />
  22 + </el-select>
  23 + </el-form-item>
  24 + </el-col>
  25 + <el-col :span="12">
  26 + <el-form-item :label="$t('addItemReleaseView.applyCompany')">
  27 + <el-input v-model="form.applyCompany"
  28 + :placeholder="$t('addItemReleaseView.requiredApplyCompany')" />
  29 + </el-form-item>
  30 + </el-col>
  31 + </el-row>
  32 +
  33 + <el-row :gutter="20">
  34 + <el-col :span="12">
  35 + <el-form-item :label="$t('addItemReleaseView.applyPerson')">
  36 + <el-input v-model="form.applyPerson" :placeholder="$t('addItemReleaseView.requiredApplyPerson')" />
  37 + </el-form-item>
  38 + </el-col>
  39 + <el-col :span="12">
  40 + <el-form-item :label="$t('addItemReleaseView.idCard')">
  41 + <el-input v-model="form.idCard" :placeholder="$t('addItemReleaseView.requiredIdCard')" />
  42 + </el-form-item>
  43 + </el-col>
  44 + </el-row>
  45 +
  46 + <el-row :gutter="20">
  47 + <el-col :span="12">
  48 + <el-form-item :label="$t('addItemReleaseView.phone')">
  49 + <el-input v-model="form.applyTel" :placeholder="$t('addItemReleaseView.requiredPhone')" />
  50 + </el-form-item>
  51 + </el-col>
  52 + <el-col :span="12">
  53 + <el-form-item :label="$t('addItemReleaseView.passTime')">
  54 + <el-date-picker v-model="form.passTime" type="datetime" style="width:100%"
  55 + :placeholder="$t('addItemReleaseView.requiredPassTime')" />
  56 + </el-form-item>
  57 + </el-col>
  58 + </el-row>
  59 +
  60 + <el-row :gutter="20">
  61 + <el-col :span="12">
  62 + <el-form-item :label="$t('addItemReleaseView.carNum')">
  63 + <el-input v-model="form.carNum" :placeholder="$t('addItemReleaseView.optionalCarNum')" />
  64 + </el-form-item>
  65 + </el-col>
  66 + <el-col :span="12">
  67 + <el-form-item :label="$t('addItemReleaseView.remark')">
  68 + <el-input v-model="form.remark" type="textarea"
  69 + :placeholder="$t('addItemReleaseView.optionalRemark')" />
  70 + </el-form-item>
  71 + </el-col>
  72 + </el-row>
  73 + </el-form>
  74 +
  75 + </el-col>
  76 + </el-row>
  77 + </el-card>
  78 +
  79 + <el-row :gutter="20" class="mt-20">
  80 + <el-col :span="24">
  81 + <el-card>
  82 + <div slot="header" class="flex justify-between">
  83 + <span>{{ $t('addItemReleaseView.releaseItems') }}</span>
  84 + <el-button type="primary" size="small" class="float-right" icon="el-icon-plus" @click="addResName">
  85 + {{ $t('addItemReleaseView.addItem') }}
  86 + </el-button>
  87 + </div>
  88 +
  89 + <el-table :data="form.resNames" border>
  90 + <el-table-column :label="$t('addItemReleaseView.itemName')" align="center">
  91 + <template slot-scope="scope">
  92 + <el-input v-model="scope.row.resName" :placeholder="$t('addItemReleaseView.requiredItemName')" />
  93 + </template>
  94 + </el-table-column>
  95 + <el-table-column :label="$t('addItemReleaseView.itemAmount')" align="center">
  96 + <template slot-scope="scope">
  97 + <el-input v-model="scope.row.amount" type="number"
  98 + :placeholder="$t('addItemReleaseView.requiredItemAmount')" />
  99 + </template>
  100 + </el-table-column>
  101 + <el-table-column :label="$t('common.operation')" align="center" width="120">
  102 + <template slot-scope="scope">
  103 + <el-button type="danger" size="small" icon="el-icon-delete"
  104 + @click="removeResName(scope.row.resName)" />
  105 + </template>
  106 + </el-table-column>
  107 + </el-table>
  108 + </el-card>
  109 + </el-col>
  110 + </el-row>
  111 +
  112 + <el-row v-if="form.audit.assignee === '-2'" :gutter="20" class="mt-20">
  113 + <el-col :span="24">
  114 +
  115 + <div slot="header" class="clearfix">
  116 + <span>{{ $t('addItemReleaseView.approverInfo') }}</span>
  117 + </div>
  118 + <el-form label-width="120px">
  119 + <el-row :gutter="20">
  120 + <el-col :span="12">
  121 + <el-form-item :label="$t('addItemReleaseView.approver')">
  122 + <el-input v-model="form.audit.staffName" :placeholder="$t('addItemReleaseView.requiredApprover')"
  123 + disabled />
  124 + </el-form-item>
  125 + </el-col>
  126 + <el-col :span="12">
  127 + <el-button type="primary" @click="chooseStaff">
  128 + <i class="el-icon-search"></i> {{ $t('common.select') }}
  129 + </el-button>
  130 + </el-col>
  131 + </el-row>
  132 + </el-form>
  133 +
  134 + </el-col>
  135 + </el-row>
  136 +
  137 + <SelectStaff ref="selectStaff" @select="handleStaffSelect" />
  138 +
  139 + <div class="mt-20 text-right">
  140 + <el-button type="warning" class="mr-20" @click="goBack">
  141 + {{ $t('common.cancel') }}
  142 + </el-button>
  143 + <el-button type="primary" @click="saveItemReleaseInfo">
  144 + {{ $t('common.submit') }}
  145 + </el-button>
  146 + </div>
  147 +
  148 + </div>
  149 +</template>
  150 +
  151 +<script>
  152 +import { getCommunityId } from '@/api/community/communityApi'
  153 +import SelectStaff from '@/components/staff/SelectStaff'
  154 +import {
  155 + saveItemRelease,
  156 + listItemReleaseType,
  157 + queryFirstAuditStaff
  158 +} from '@/api/work/addItemReleaseViewApi'
  159 +
  160 +export default {
  161 + name: 'AddItemReleaseView',
  162 + components: {
  163 + SelectStaff
  164 + },
  165 + data() {
  166 + return {
  167 + form: {
  168 + irId: '',
  169 + typeId: '',
  170 + applyCompany: '',
  171 + applyPerson: '',
  172 + idCard: '',
  173 + applyTel: '',
  174 + passTime: '',
  175 + resNames: [],
  176 + state: '',
  177 + carNum: '',
  178 + remark: '',
  179 + itemReleaseTypes: [],
  180 + audit: {
  181 + assignee: '',
  182 + staffId: '',
  183 + staffName: '',
  184 + taskId: ''
  185 + },
  186 + communityId: ''
  187 + }
  188 + }
  189 + },
  190 + created() {
  191 + this.communityId = getCommunityId()
  192 + this.listItemReleaseTypes()
  193 + },
  194 + methods: {
  195 + goBack() {
  196 + this.$router.go(-1)
  197 + },
  198 + validateForm() {
  199 + if (!this.form.typeId) {
  200 + this.$message.error(this.$t('addItemReleaseView.validate.releaseType'))
  201 + return false
  202 + }
  203 + if (!this.form.applyCompany) {
  204 + this.$message.error(this.$t('addItemReleaseView.validate.applyCompany'))
  205 + return false
  206 + }
  207 + if (!this.form.applyPerson) {
  208 + this.$message.error(this.$t('addItemReleaseView.validate.applyPerson'))
  209 + return false
  210 + }
  211 + if (!this.form.idCard) {
  212 + this.$message.error(this.$t('addItemReleaseView.validate.idCard'))
  213 + return false
  214 + }
  215 + if (!this.form.applyTel) {
  216 + this.$message.error(this.$t('addItemReleaseView.validate.phone'))
  217 + return false
  218 + }
  219 + if (!this.form.passTime) {
  220 + this.$message.error(this.$t('addItemReleaseView.validate.passTime'))
  221 + return false
  222 + }
  223 + if (this.form.resNames.length === 0) {
  224 + this.$message.error(this.$t('addItemReleaseView.validate.itemsRequired'))
  225 + return false
  226 + }
  227 + for (const item of this.form.resNames) {
  228 + if (!item.resName || !item.amount) {
  229 + this.$message.error(this.$t('addItemReleaseView.validate.itemInfoRequired'))
  230 + return false
  231 + }
  232 + }
  233 + if (this.form.audit.assignee === '-2' && !this.form.audit.staffId) {
  234 + this.$message.error(this.$t('addItemReleaseView.validate.approverRequired'))
  235 + return false
  236 + }
  237 + return true
  238 + },
  239 + async saveItemReleaseInfo() {
  240 + if (!this.validateForm()) return
  241 +
  242 + try {
  243 + this.form.communityId = this.communityId
  244 + const res = await saveItemRelease(this.form)
  245 + if (res.code === 0) {
  246 + this.$message.success(this.$t('common.saveSuccess'))
  247 + this.goBack()
  248 + } else {
  249 + this.$message.error(res.msg)
  250 + }
  251 + } catch (error) {
  252 + this.$message.error(this.$t('common.saveFailed'))
  253 + }
  254 + },
  255 + async listItemReleaseTypes() {
  256 + try {
  257 + const params = {
  258 + page: 1,
  259 + row: 100,
  260 + communityId: this.communityId
  261 + }
  262 + const res = await listItemReleaseType(params)
  263 + this.form.itemReleaseTypes = res.data
  264 + } catch (error) {
  265 + this.$message.error(this.$t('common.fetchFailed'))
  266 + }
  267 + },
  268 + addResName() {
  269 + this.form.resNames.push({
  270 + resName: '',
  271 + amount: ''
  272 + })
  273 + },
  274 + removeResName(resName) {
  275 + this.form.resNames = this.form.resNames.filter(item => item.resName !== resName)
  276 + },
  277 + async changeItemReleaseType() {
  278 + const selectedType = this.form.itemReleaseTypes.find(
  279 + item => item.typeId === this.form.typeId
  280 + )
  281 + if (selectedType && selectedType.flowId) {
  282 + await this.loadStaffOrg(selectedType.flowId)
  283 + }
  284 + },
  285 + async loadStaffOrg(flowId) {
  286 + try {
  287 + const params = {
  288 + communityId: this.communityId,
  289 + flowId: flowId
  290 + }
  291 + const res = await queryFirstAuditStaff(params)
  292 + if (res.code === 0 && res.data.length > 0) {
  293 + Object.assign(this.form.audit, res.data[0])
  294 + if (!res.data[0].assignee.startsWith('-')) {
  295 + this.form.audit.staffId = res.data[0].assignee
  296 + }
  297 + }
  298 + } catch (error) {
  299 + console.error('Failed to load staff org:', error)
  300 + }
  301 + },
  302 + chooseStaff() {
  303 + this.$refs.selectStaff.open(this.form.audit)
  304 + },
  305 + handleStaffSelect(staff) {
  306 + this.form.audit.staffId = staff.staffId
  307 + this.form.audit.staffName = staff.staffName
  308 + }
  309 + }
  310 +}
  311 +</script>
  312 +
  313 +<style scoped>
  314 +.add-item-release-view-container {
  315 + padding: 20px;
  316 +}
  317 +
  318 +.mt-20 {
  319 + margin-top: 20px;
  320 +}
  321 +
  322 +.mr-20 {
  323 + margin-right: 20px;
  324 +}
  325 +
  326 +.float-right {
  327 + float: right;
  328 +}
  329 +
  330 +.text-right {
  331 + text-align: right;
  332 +}
  333 +</style>
0 334 \ No newline at end of file
... ...
src/views/work/itemReleaseManageLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + itemReleaseManage: {
  4 + search: {
  5 + title: 'Search Conditions',
  6 + more: 'More',
  7 + hide: 'Hide'
  8 + },
  9 + list: {
  10 + title: 'Item Release'
  11 + },
  12 + form: {
  13 + releaseType: 'Release Type',
  14 + applyCompany: 'Apply Company',
  15 + applyPerson: 'Applicant',
  16 + idCard: 'ID Card',
  17 + phone: 'Phone',
  18 + passTime: 'Pass Time',
  19 + releaseItems: 'Release Items',
  20 + itemAmount: 'Item Amount',
  21 + status: 'Status',
  22 + carNumber: 'Car Number',
  23 + remark: 'Remark'
  24 + },
  25 + table: {
  26 + orderNo: 'Order No',
  27 + releaseType: 'Release Type',
  28 + applyCompany: 'Apply Company',
  29 + applyPerson: 'Applicant',
  30 + idCard: 'ID Card',
  31 + phone: 'Phone',
  32 + passTime: 'Pass Time',
  33 + items: 'Items',
  34 + status: 'Status',
  35 + carNumber: 'Car Number'
  36 + },
  37 + button: {
  38 + applyRelease: 'Apply Release',
  39 + viewItems: 'View Items'
  40 + },
  41 + placeholder: {
  42 + selectReleaseType: 'Please select release type',
  43 + selectApplyCompany: 'Please select apply company',
  44 + selectApplyPerson: 'Please select applicant',
  45 + selectIdCard: 'Please input ID card',
  46 + selectPhone: 'Please input phone',
  47 + selectStatus: 'Please select status',
  48 + requiredSelect: 'Required, please select',
  49 + requiredInput: 'Required, please input',
  50 + optionalInput: 'Optional, please input'
  51 + },
  52 + status: {
  53 + waiting: 'Waiting',
  54 + processing: 'Processing',
  55 + completed: 'Completed',
  56 + failed: 'Failed'
  57 + },
  58 + validate: {
  59 + required: 'Cannot be empty',
  60 + maxLength30: 'Cannot exceed 30 characters',
  61 + maxLength64: 'Cannot exceed 64 characters',
  62 + maxLength18: 'Cannot exceed 18 characters',
  63 + maxLength11: 'Cannot exceed 11 characters',
  64 + maxLength12: 'Cannot exceed 12 characters',
  65 + maxLength512: 'Cannot exceed 512 characters'
  66 + },
  67 + edit: {
  68 + title: 'Edit Item Release'
  69 + },
  70 + delete: {
  71 + confirmDelete: 'Confirm to delete item release?'
  72 + },
  73 + viewItems: {
  74 + title: 'Release Items',
  75 + itemName: 'Item Name',
  76 + amount: 'Amount'
  77 + }
  78 + }
  79 + },
  80 + zh: {
  81 + itemReleaseManage: {
  82 + search: {
  83 + title: '查询条件',
  84 + more: '更多',
  85 + hide: '隐藏'
  86 + },
  87 + list: {
  88 + title: '物品放行'
  89 + },
  90 + form: {
  91 + releaseType: '放行类型',
  92 + applyCompany: '申请单位',
  93 + applyPerson: '申请人',
  94 + idCard: '身份证',
  95 + phone: '手机号',
  96 + passTime: '通行时间',
  97 + releaseItems: '放行物品',
  98 + itemAmount: '物品数量',
  99 + status: '状态',
  100 + carNumber: '车牌号',
  101 + remark: '备注'
  102 + },
  103 + table: {
  104 + orderNo: '单号',
  105 + releaseType: '放行类型',
  106 + applyCompany: '申请单位',
  107 + applyPerson: '申请人',
  108 + idCard: '身份证',
  109 + phone: '手机号',
  110 + passTime: '通行时间',
  111 + items: '物品',
  112 + status: '状态',
  113 + carNumber: '车牌号'
  114 + },
  115 + button: {
  116 + applyRelease: '申请放行',
  117 + viewItems: '查看物品'
  118 + },
  119 + placeholder: {
  120 + selectReleaseType: '请选择放行类型',
  121 + selectApplyCompany: '请选择申请单位',
  122 + selectApplyPerson: '请选择申请人',
  123 + selectIdCard: '请输入身份证',
  124 + selectPhone: '请输入手机号',
  125 + selectStatus: '请选择状态',
  126 + requiredSelect: '必填,请选择',
  127 + requiredInput: '必填,请输入',
  128 + optionalInput: '选填,请输入'
  129 + },
  130 + status: {
  131 + waiting: '待审核',
  132 + processing: '审核中',
  133 + completed: '审核完成',
  134 + failed: '审核失败'
  135 + },
  136 + validate: {
  137 + required: '不能为空',
  138 + maxLength30: '不能超过30个字符',
  139 + maxLength64: '不能超过64个字符',
  140 + maxLength18: '不能超过18个字符',
  141 + maxLength11: '不能超过11个字符',
  142 + maxLength12: '不能超过12个字符',
  143 + maxLength512: '不能超过512个字符'
  144 + },
  145 + edit: {
  146 + title: '修改物品放行'
  147 + },
  148 + delete: {
  149 + confirmDelete: '确定删除物品放行?'
  150 + },
  151 + viewItems: {
  152 + title: '放行物品',
  153 + itemName: '物品名称',
  154 + amount: '数量'
  155 + }
  156 + }
  157 + }
  158 +}
0 159 \ No newline at end of file
... ...
src/views/work/itemReleaseManageList.vue 0 → 100644
  1 +<template>
  2 + <div class="item-release-manage-container">
  3 + <!-- 查询条件 -->
  4 + <el-card class="search-card">
  5 + <div slot="header" class="flex justify-between">
  6 + <span>{{ $t('itemReleaseManage.search.title') }}</span>
  7 + <el-button
  8 + type="text"
  9 + style="float: right; padding: 3px 0"
  10 + @click="_moreCondition"
  11 + >
  12 + {{ itemReleaseManageInfo.moreCondition ? $t('common.hide') : $t('common.more') }}
  13 + </el-button>
  14 + </div>
  15 + <el-row :gutter="20">
  16 + <el-col :span="6">
  17 + <el-select
  18 + v-model="itemReleaseManageInfo.conditions.typeId"
  19 + :placeholder="$t('itemReleaseManage.placeholder.selectReleaseType')"
  20 + style="width: 100%"
  21 + >
  22 + <el-option
  23 + v-for="item in itemReleaseManageInfo.itemReleaseTypes"
  24 + :key="item.typeId"
  25 + :label="item.typeName"
  26 + :value="item.typeId"
  27 + :disabled="item.state !== 'C'"
  28 + />
  29 + </el-select>
  30 + </el-col>
  31 + <el-col :span="8">
  32 + <el-input
  33 + v-model="itemReleaseManageInfo.conditions.applyCompany"
  34 + :placeholder="$t('itemReleaseManage.placeholder.selectApplyCompany')"
  35 + />
  36 + </el-col>
  37 + <el-col :span="6">
  38 + <el-input
  39 + v-model="itemReleaseManageInfo.conditions.applyPerson"
  40 + :placeholder="$t('itemReleaseManage.placeholder.selectApplyPerson')"
  41 + />
  42 + </el-col>
  43 + <el-col :span="4">
  44 + <el-button type="primary" @click="_queryItemReleaseMethod">
  45 + <i class="el-icon-search"></i>
  46 + {{ $t('common.search') }}
  47 + </el-button>
  48 + <el-button @click="_resetItemReleaseMethod">
  49 + <i class="el-icon-refresh"></i>
  50 + {{ $t('common.reset') }}
  51 + </el-button>
  52 + </el-col>
  53 + </el-row>
  54 +
  55 + <el-row v-show="itemReleaseManageInfo.moreCondition" :gutter="20" style="margin-top: 20px">
  56 + <el-col :span="6">
  57 + <el-input
  58 + v-model="itemReleaseManageInfo.conditions.idCard"
  59 + :placeholder="$t('itemReleaseManage.placeholder.selectIdCard')"
  60 + />
  61 + </el-col>
  62 + <el-col :span="8">
  63 + <el-input
  64 + v-model="itemReleaseManageInfo.conditions.applyTel"
  65 + :placeholder="$t('itemReleaseManage.placeholder.selectPhone')"
  66 + />
  67 + </el-col>
  68 + <el-col :span="6">
  69 + <el-select
  70 + v-model="itemReleaseManageInfo.conditions.state"
  71 + :placeholder="$t('itemReleaseManage.placeholder.selectStatus')"
  72 + style="width: 100%"
  73 + >
  74 + <el-option
  75 + :label="$t('itemReleaseManage.status.waiting')"
  76 + value="W"
  77 + />
  78 + <el-option
  79 + :label="$t('itemReleaseManage.status.processing')"
  80 + value="D"
  81 + />
  82 + <el-option
  83 + :label="$t('itemReleaseManage.status.completed')"
  84 + value="C"
  85 + />
  86 + <el-option
  87 + :label="$t('itemReleaseManage.status.failed')"
  88 + value="F"
  89 + />
  90 + </el-select>
  91 + </el-col>
  92 + </el-row>
  93 + </el-card>
  94 +
  95 + <!-- 物品放行列表 -->
  96 + <el-card class="list-card">
  97 + <div slot="header" class="flex justify-between">
  98 + <span>{{ $t('itemReleaseManage.list.title') }}</span>
  99 + <el-button
  100 + type="primary"
  101 + size="small"
  102 + @click="_openAddItemReleaseModal"
  103 + >
  104 + <i class="el-icon-plus"></i>
  105 + {{ $t('itemReleaseManage.button.applyRelease') }}
  106 + </el-button>
  107 + </div>
  108 +
  109 + <el-table
  110 + :data="itemReleaseManageInfo.itemReleases"
  111 + border
  112 + style="width: 100%"
  113 + v-loading="loading"
  114 + >
  115 + <el-table-column
  116 + prop="irId"
  117 + :label="$t('itemReleaseManage.table.orderNo')"
  118 + align="center"
  119 + />
  120 + <el-table-column
  121 + prop="typeName"
  122 + :label="$t('itemReleaseManage.table.releaseType')"
  123 + align="center"
  124 + />
  125 + <el-table-column
  126 + prop="applyCompany"
  127 + :label="$t('itemReleaseManage.table.applyCompany')"
  128 + align="center"
  129 + />
  130 + <el-table-column
  131 + prop="applyPerson"
  132 + :label="$t('itemReleaseManage.table.applyPerson')"
  133 + align="center"
  134 + />
  135 + <el-table-column
  136 + prop="idCard"
  137 + :label="$t('itemReleaseManage.table.idCard')"
  138 + align="center"
  139 + />
  140 + <el-table-column
  141 + prop="applyTel"
  142 + :label="$t('itemReleaseManage.table.phone')"
  143 + align="center"
  144 + />
  145 + <el-table-column
  146 + prop="passTime"
  147 + :label="$t('itemReleaseManage.table.passTime')"
  148 + align="center"
  149 + />
  150 + <el-table-column
  151 + :label="$t('itemReleaseManage.table.items')"
  152 + align="center"
  153 + >
  154 + <template slot-scope="scope">
  155 + {{ scope.row.amount }}(
  156 + <el-link type="primary" @click="viewResName(scope.row)">
  157 + {{ $t('itemReleaseManage.button.viewItems') }}
  158 + </el-link>)
  159 + </template>
  160 + </el-table-column>
  161 + <el-table-column
  162 + prop="stateName"
  163 + :label="$t('itemReleaseManage.table.status')"
  164 + align="center"
  165 + />
  166 + <el-table-column
  167 + prop="carNum"
  168 + :label="$t('itemReleaseManage.table.carNumber')"
  169 + align="center"
  170 + >
  171 + <template slot-scope="scope">
  172 + {{ scope.row.carNum || $t('common.none') }}
  173 + </template>
  174 + </el-table-column>
  175 + <el-table-column
  176 + :label="$t('common.operation')"
  177 + align="center"
  178 + width="240"
  179 + >
  180 + <template slot-scope="scope">
  181 + <el-button
  182 + size="mini"
  183 + @click="_openDetail(scope.row)"
  184 + >
  185 + {{ $t('common.detail') }}
  186 + </el-button>
  187 + <el-button
  188 + size="mini"
  189 + type="primary"
  190 + @click="_openEditItemReleaseModel(scope.row)"
  191 + >
  192 + {{ $t('common.edit') }}
  193 + </el-button>
  194 + <el-button
  195 + size="mini"
  196 + type="danger"
  197 + @click="_openDeleteItemReleaseModel(scope.row)"
  198 + >
  199 + {{ $t('common.delete') }}
  200 + </el-button>
  201 + </template>
  202 + </el-table-column>
  203 + </el-table>
  204 +
  205 + <el-pagination
  206 + :current-page.sync="page.current"
  207 + :page-sizes="[10, 20, 30, 50]"
  208 + :page-size="page.size"
  209 + :total="page.total"
  210 + layout="total, sizes, prev, pager, next, jumper"
  211 + @size-change="handleSizeChange"
  212 + @current-change="handleCurrentChange"
  213 + style="margin-top: 20px"
  214 + />
  215 + </el-card>
  216 +
  217 + <!-- 组件 -->
  218 + <edit-item-release ref="editItemRelease" @success="handleSuccess" />
  219 + <delete-item-release ref="deleteItemRelease" @success="handleSuccess" />
  220 + <view-item-release-res ref="viewItemReleaseRes" />
  221 + </div>
  222 +</template>
  223 +
  224 +<script>
  225 +import { getCommunityId } from '@/api/community/communityApi'
  226 +import { listItemRelease, listItemReleaseType } from '@/api/work/itemReleaseManageApi'
  227 +import EditItemRelease from '@/components/work/editItemRelease'
  228 +import DeleteItemRelease from '@/components/work/deleteItemRelease'
  229 +import ViewItemReleaseRes from '@/components/work/viewItemReleaseRes'
  230 +
  231 +export default {
  232 + name: 'ItemReleaseManageList',
  233 + components: {
  234 + EditItemRelease,
  235 + DeleteItemRelease,
  236 + ViewItemReleaseRes
  237 + },
  238 + data() {
  239 + return {
  240 + loading: false,
  241 + communityId: '',
  242 + itemReleaseManageInfo: {
  243 + itemReleases: [],
  244 + total: 0,
  245 + records: 1,
  246 + moreCondition: false,
  247 + irId: '',
  248 + itemReleaseTypes: [],
  249 + conditions: {
  250 + typeId: '',
  251 + applyCompany: '',
  252 + applyPerson: '',
  253 + idCard: '',
  254 + applyTel: '',
  255 + state: '',
  256 + communityId: ''
  257 + }
  258 + },
  259 + page: {
  260 + current: 1,
  261 + size: 10,
  262 + total: 0
  263 + }
  264 + }
  265 + },
  266 + created() {
  267 + this.communityId = getCommunityId()
  268 + this.itemReleaseManageInfo.conditions.communityId = this.communityId
  269 + this._listItemReleases(this.page.current, this.page.size)
  270 + this._listItemReleaseTypes()
  271 + },
  272 + methods: {
  273 + async _listItemReleases(page, rows) {
  274 + try {
  275 + this.loading = true
  276 + const params = {
  277 + page,
  278 + row: rows,
  279 + ...this.itemReleaseManageInfo.conditions
  280 + }
  281 + const { data, total } = await listItemRelease(params)
  282 + this.itemReleaseManageInfo.itemReleases = data
  283 + this.page.total = total
  284 + } catch (error) {
  285 + console.error('获取物品放行列表失败:', error)
  286 + } finally {
  287 + this.loading = false
  288 + }
  289 + },
  290 + async _listItemReleaseTypes() {
  291 + try {
  292 + const params = {
  293 + page: 1,
  294 + row: 100,
  295 + communityId: this.communityId
  296 + }
  297 + const { data } = await listItemReleaseType(params)
  298 + this.itemReleaseManageInfo.itemReleaseTypes = data
  299 + } catch (error) {
  300 + console.error('获取放行类型失败:', error)
  301 + }
  302 + },
  303 + _openAddItemReleaseModal() {
  304 + this.$router.push('/views/work/addItemReleaseView')
  305 + },
  306 + _openEditItemReleaseModel(item) {
  307 + this.$refs.editItemRelease.open(item)
  308 + },
  309 + _openDeleteItemReleaseModel(item) {
  310 + this.$refs.deleteItemRelease.open(item)
  311 + },
  312 + _queryItemReleaseMethod() {
  313 + this.page.current = 1
  314 + this._listItemReleases(this.page.current, this.page.size)
  315 + },
  316 + _resetItemReleaseMethod() {
  317 + this.itemReleaseManageInfo.conditions = {
  318 + typeId: '',
  319 + applyCompany: '',
  320 + applyPerson: '',
  321 + idCard: '',
  322 + applyTel: '',
  323 + state: '',
  324 + communityId: this.communityId
  325 + }
  326 + this.page.current = 1
  327 + this._listItemReleases(this.page.current, this.page.size)
  328 + },
  329 + _moreCondition() {
  330 + this.itemReleaseManageInfo.moreCondition = !this.itemReleaseManageInfo.moreCondition
  331 + },
  332 + viewResName(item) {
  333 + this.$refs.viewItemReleaseRes.open(item)
  334 + },
  335 + _openDetail(item) {
  336 + this.$router.push(`/views/work/itemReleaseDetail?irId=${item.irId}&flowId=${item.flowId}`)
  337 + },
  338 + handleSuccess() {
  339 + this._listItemReleases(this.page.current, this.page.size)
  340 + },
  341 + handleSizeChange(val) {
  342 + this.page.size = val
  343 + this._listItemReleases(this.page.current, val)
  344 + },
  345 + handleCurrentChange(val) {
  346 + this.page.current = val
  347 + this._listItemReleases(val, this.page.size)
  348 + }
  349 + }
  350 +}
  351 +</script>
  352 +
  353 +<style lang="scss" scoped>
  354 +.item-release-manage-container {
  355 + padding: 20px;
  356 +
  357 + .search-card {
  358 + margin-bottom: 20px;
  359 + }
  360 +
  361 + .list-card {
  362 + margin-bottom: 20px;
  363 + }
  364 +
  365 + .el-select {
  366 + width: 100%;
  367 + }
  368 +}
  369 +</style>
0 370 \ No newline at end of file
... ...
src/views/work/itemReleaseTypeManageLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + itemReleaseTypeManage: {
  4 + search: {
  5 + title: 'Search Conditions',
  6 + typeNamePlaceholder: 'Please enter type name'
  7 + },
  8 + list: {
  9 + title: 'Release Types'
  10 + },
  11 + table: {
  12 + typeId: 'ID',
  13 + typeName: 'Type Name',
  14 + flowName: 'Flow Name',
  15 + setFlow: 'Set Flow',
  16 + state: 'Status',
  17 + deployed: 'Deployed',
  18 + pendingDeploy: 'Pending Deploy',
  19 + remark: 'Remark',
  20 + deploy: 'Deploy'
  21 + },
  22 + form: {
  23 + typeName: 'Type Name',
  24 + typeNamePlaceholder: 'Required, please enter type name',
  25 + remark: 'Remark',
  26 + remarkPlaceholder: 'Required, please enter remark'
  27 + },
  28 + validate: {
  29 + typeNameRequired: 'Type name is required',
  30 + typeNameMaxLength: 'Type name cannot exceed 30 characters',
  31 + remarkRequired: 'Remark is required',
  32 + remarkMaxLength: 'Remark cannot exceed 512 characters',
  33 + typeIdRequired: 'Type ID is required'
  34 + },
  35 + add: {
  36 + title: 'Add Release Type',
  37 + success: 'Add successfully',
  38 + error: 'Add failed'
  39 + },
  40 + edit: {
  41 + title: 'Edit Release Type',
  42 + success: 'Edit successfully',
  43 + error: 'Edit failed'
  44 + },
  45 + delete: {
  46 + title: 'Delete Confirmation',
  47 + confirmText: 'Are you sure to delete this release type?',
  48 + success: 'Delete successfully',
  49 + error: 'Delete failed'
  50 + },
  51 + fetchError: 'Failed to fetch data',
  52 + deploySuccess: 'Deploy successfully',
  53 + deployError: 'Deploy failed'
  54 + }
  55 + },
  56 + zh: {
  57 + itemReleaseTypeManage: {
  58 + search: {
  59 + title: '查询条件',
  60 + typeNamePlaceholder: '请输入类型名称'
  61 + },
  62 + list: {
  63 + title: '放行类型'
  64 + },
  65 + table: {
  66 + typeId: '编号',
  67 + typeName: '类型名称',
  68 + flowName: '流程名称',
  69 + setFlow: '设置流程',
  70 + state: '状态',
  71 + deployed: '已部署',
  72 + pendingDeploy: '待部署',
  73 + remark: '备注',
  74 + deploy: '部署'
  75 + },
  76 + form: {
  77 + typeName: '类型名称',
  78 + typeNamePlaceholder: '必填,请填写类型名称',
  79 + remark: '备注',
  80 + remarkPlaceholder: '必填,请填写备注'
  81 + },
  82 + validate: {
  83 + typeNameRequired: '类型名称不能为空',
  84 + typeNameMaxLength: '类型名称不能超过30个字符',
  85 + remarkRequired: '备注不能为空',
  86 + remarkMaxLength: '备注不能超过512个字符',
  87 + typeIdRequired: '编号不能为空'
  88 + },
  89 + add: {
  90 + title: '添加放行类型',
  91 + success: '添加成功',
  92 + error: '添加失败'
  93 + },
  94 + edit: {
  95 + title: '修改放行类型',
  96 + success: '修改成功',
  97 + error: '修改失败'
  98 + },
  99 + delete: {
  100 + title: '删除确认',
  101 + confirmText: '确定删除该放行类型吗?',
  102 + success: '删除成功',
  103 + error: '删除失败'
  104 + },
  105 + fetchError: '获取数据失败',
  106 + deploySuccess: '部署成功',
  107 + deployError: '部署失败'
  108 + }
  109 + }
  110 +}
0 111 \ No newline at end of file
... ...
src/views/work/itemReleaseTypeManageList.vue 0 → 100644
  1 +<template>
  2 + <div class="item-release-type-manage-container">
  3 + <!-- 查询条件 -->
  4 + <el-card class="search-wrapper">
  5 + <div slot="header" class="flex justify-between">
  6 + <span>{{ $t('itemReleaseTypeManage.search.title') }}</span>
  7 + </div>
  8 + <el-row :gutter="20">
  9 + <el-col :span="6">
  10 + <el-input v-model="searchForm.typeName" :placeholder="$t('itemReleaseTypeManage.search.typeNamePlaceholder')"
  11 + clearable />
  12 + </el-col>
  13 + <el-col :span="4">
  14 + <el-button type="primary" @click="handleSearch">
  15 + <i class="el-icon-search"></i>
  16 + {{ $t('common.search') }}
  17 + </el-button>
  18 + <el-button @click="handleReset">
  19 + <i class="el-icon-refresh"></i>
  20 + {{ $t('common.reset') }}
  21 + </el-button>
  22 + </el-col>
  23 + </el-row>
  24 + </el-card>
  25 +
  26 + <!-- 放行类型列表 -->
  27 + <el-card class="list-wrapper">
  28 + <div slot="header" class="flex justify-between">
  29 + <span>{{ $t('itemReleaseTypeManage.list.title') }}</span>
  30 + <el-button type="primary" size="small" class="float-right" @click="handleAdd">
  31 + <i class="el-icon-plus"></i>
  32 + {{ $t('common.add') }}
  33 + </el-button>
  34 + </div>
  35 +
  36 + <el-table v-loading="loading" :data="tableData" border style="width: 100%">
  37 + <el-table-column prop="typeId" :label="$t('itemReleaseTypeManage.table.typeId')" align="center" />
  38 + <el-table-column prop="typeName" :label="$t('itemReleaseTypeManage.table.typeName')" align="center" />
  39 + <el-table-column :label="$t('itemReleaseTypeManage.table.flowName')" align="center">
  40 + <template slot-scope="scope">
  41 + {{ scope.row.flowName }}
  42 + <el-link type="primary" @click="handleSettingFlow(scope.row)">
  43 + ({{ $t('itemReleaseTypeManage.table.setFlow') }})
  44 + </el-link>
  45 + </template>
  46 + </el-table-column>
  47 + <el-table-column :label="$t('itemReleaseTypeManage.table.state')" align="center">
  48 + <template slot-scope="scope">
  49 + {{ scope.row.state === 'C' ? $t('itemReleaseTypeManage.table.deployed') :
  50 + $t('itemReleaseTypeManage.table.pendingDeploy') }}
  51 + </template>
  52 + </el-table-column>
  53 + <el-table-column prop="remark" :label="$t('itemReleaseTypeManage.table.remark')" align="center" />
  54 + <el-table-column :label="$t('common.operation')" align="center" width="250">
  55 + <template slot-scope="scope">
  56 + <el-button v-if="scope.row.state === 'W'" size="mini" type="primary" @click="handleDeploy(scope.row)">
  57 + {{ $t('itemReleaseTypeManage.table.deploy') }}
  58 + </el-button>
  59 + <el-button size="mini" type="primary" @click="handleEdit(scope.row)">
  60 + {{ $t('common.edit') }}
  61 + </el-button>
  62 + <el-button size="mini" type="danger" @click="handleDelete(scope.row)">
  63 + {{ $t('common.delete') }}
  64 + </el-button>
  65 + </template>
  66 + </el-table-column>
  67 + </el-table>
  68 +
  69 + <el-pagination :current-page.sync="pagination.current" :page-sizes="[10, 20, 30, 50]" :page-size="pagination.size"
  70 + :total="pagination.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
  71 + @current-change="handleCurrentChange" />
  72 + </el-card>
  73 +
  74 + <!-- 添加弹窗 -->
  75 + <add-item-release-type ref="addDialog" @success="handleSuccess" />
  76 +
  77 + <!-- 编辑弹窗 -->
  78 + <edit-item-release-type ref="editDialog" @success="handleSuccess" />
  79 +
  80 + <!-- 删除弹窗 -->
  81 + <delete-item-release-type ref="deleteDialog" @success="handleSuccess" />
  82 + </div>
  83 +</template>
  84 +
  85 +<script>
  86 +import { listItemReleaseType, deployModel } from '@/api/work/itemReleaseTypeManageApi'
  87 +import AddItemReleaseType from '@/components/work/addItemReleaseType'
  88 +import EditItemReleaseType from '@/components/work/editItemReleaseType'
  89 +import DeleteItemReleaseType from '@/components/work/deleteItemReleaseType'
  90 +import { getCommunityId } from '@/api/community/communityApi'
  91 +
  92 +export default {
  93 + name: 'ItemReleaseTypeManageList',
  94 + components: {
  95 + AddItemReleaseType,
  96 + EditItemReleaseType,
  97 + DeleteItemReleaseType
  98 + },
  99 + data() {
  100 + return {
  101 + loading: false,
  102 + searchForm: {
  103 + typeName: '',
  104 + communityId: ''
  105 + },
  106 + tableData: [],
  107 + pagination: {
  108 + current: 1,
  109 + size: 10,
  110 + total: 0
  111 + }
  112 + }
  113 + },
  114 + created() {
  115 + this.searchForm.communityId = getCommunityId()
  116 + this.getList()
  117 + },
  118 + methods: {
  119 + async getList() {
  120 + try {
  121 + this.loading = true
  122 + const params = {
  123 + page: this.pagination.current,
  124 + row: this.pagination.size,
  125 + ...this.searchForm
  126 + }
  127 + const { data, total } = await listItemReleaseType(params)
  128 + this.tableData = data
  129 + this.pagination.total = total
  130 + } catch (error) {
  131 + this.$message.error(this.$t('itemReleaseTypeManage.fetchError'))
  132 + } finally {
  133 + this.loading = false
  134 + }
  135 + },
  136 + handleSearch() {
  137 + this.pagination.current = 1
  138 + this.getList()
  139 + },
  140 + handleReset() {
  141 + this.searchForm.typeName = ''
  142 + this.handleSearch()
  143 + },
  144 + handleAdd() {
  145 + this.$refs.addDialog.open()
  146 + },
  147 + handleEdit(row) {
  148 + this.$refs.editDialog.open(row)
  149 + },
  150 + handleDelete(row) {
  151 + this.$refs.deleteDialog.open(row)
  152 + },
  153 + async handleDeploy(row) {
  154 + try {
  155 + await deployModel({ modelId: row.modelId })
  156 + this.$message.success(this.$t('itemReleaseTypeManage.deploySuccess'))
  157 + this.getList()
  158 + } catch (error) {
  159 + this.$message.error(this.$t('itemReleaseTypeManage.deployError'))
  160 + }
  161 + },
  162 + handleSettingFlow(row) {
  163 + window.open(`/bpmnjs/index.html?flowId=${row.flowId}&modelId=${row.modelId}`)
  164 + },
  165 + handleSuccess() {
  166 + this.getList()
  167 + },
  168 + handleSizeChange(val) {
  169 + this.pagination.size = val
  170 + this.getList()
  171 + },
  172 + handleCurrentChange(val) {
  173 + this.pagination.current = val
  174 + this.getList()
  175 + }
  176 + }
  177 +}
  178 +</script>
  179 +
  180 +<style lang="scss" scoped>
  181 +.item-release-type-manage-container {
  182 + padding: 20px;
  183 +
  184 + .search-wrapper {
  185 + margin-bottom: 20px;
  186 + }
  187 +
  188 + .list-wrapper {
  189 + margin-bottom: 20px;
  190 + }
  191 +
  192 + .el-pagination {
  193 + margin-top: 20px;
  194 + text-align: right;
  195 + }
  196 +}
  197 +</style>
0 198 \ No newline at end of file
... ...