Compare commits
	
		
			8 Commits
		
	
	
		
			6b030791bb
			...
			feature/nu
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 17bf8599d1 | ||
|  | 45017af56d | ||
|  | 2f93572701 | ||
|  | 64f08839e2 | ||
|  | d52cbffed7 | ||
|  | 0e7cb83bd4 | ||
|  | bc8b161020 | ||
|  | d2e63c2588 | 
							
								
								
									
										2
									
								
								.env.ai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.env.ai
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | VUE_APP_SCOPE=ai | ||||||
|  | VUE_APP_API=http://192.168.1.87:9000 | ||||||
							
								
								
									
										5
									
								
								.env.biaopin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.env.biaopin
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | VUE_APP_SCOPE=biaopin | ||||||
|  | #VUE_APP_API=https://web.fdfengshou.cn/ | ||||||
|  | #VUE_APP_API=http://192.168.1.87:9000/ | ||||||
|  | VUE_APP_API=https://www.wyzzb.com | ||||||
|  | #VUE_APP_API=http://test87web.cunwuyun.cn/ | ||||||
							
								
								
									
										2
									
								
								.env.dv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.env.dv
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | VUE_APP_SCOPE=dv | ||||||
|  | VUE_APP_API=http://192.168.1.87:9000 | ||||||
							
								
								
									
										4
									
								
								.env.fengdu
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.env.fengdu
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | VUE_APP_SCOPE=fengdu | ||||||
|  | #VUE_APP_API=https://web.fdfengshou.cn/ | ||||||
|  | VUE_APP_API=http://192.168.1.87:9000/ | ||||||
|  | #VUE_APP_API=http://test87web.cunwuyun.cn/ | ||||||
| @@ -1,5 +0,0 @@ | |||||||
| VUE_APP_SCOPE=xumu |  | ||||||
| VUE_APP_API=http://192.168.1.87:12413 |  | ||||||
| VUE_APP_IS_SIMPLE_SERVER=1 |  | ||||||
| VUE_APP_PORT=12413 |  | ||||||
| VUE_APP_OMS_ID=2cd70a15-a3cf-4b4d-9a22-0f3b3a888b08   # oms定制方案的ID |  | ||||||
							
								
								
									
										29
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -27,7 +27,32 @@ yarn-error.log* | |||||||
| /project/*/dist | /project/*/dist | ||||||
| /ui/package-lock.json | /ui/package-lock.json | ||||||
| /examples/modules.json | /examples/modules.json | ||||||
| /examples/router/apps.js |  | ||||||
|  |  | ||||||
| /src/apps/ | /src/apps/ | ||||||
| /src/config.json | /src/config.json | ||||||
| /src/utils/apps.js | /.nuxt/components/nuxt.js | ||||||
|  | /.nuxt/components/nuxt-build-indicator.vue | ||||||
|  | /.nuxt/components/nuxt-child.js | ||||||
|  | /.nuxt/components/nuxt-error.vue | ||||||
|  | /.nuxt/components/nuxt-link.client.js | ||||||
|  | /.nuxt/components/nuxt-link.server.js | ||||||
|  | /.nuxt/components/nuxt-loading.vue | ||||||
|  | /.nuxt/layouts/default.vue | ||||||
|  | /.nuxt/mixins/fetch.client.js | ||||||
|  | /.nuxt/mixins/fetch.server.js | ||||||
|  | /.nuxt/views/app.template.html | ||||||
|  | /.nuxt/views/error.html | ||||||
|  | /.nuxt/App.js | ||||||
|  | /.nuxt/client.js | ||||||
|  | /.nuxt/empty.js | ||||||
|  | /.nuxt/index.js | ||||||
|  | /.nuxt/jsonp.js | ||||||
|  | /.nuxt/loading.html | ||||||
|  | /.nuxt/middleware.js | ||||||
|  | /.nuxt/router.js | ||||||
|  | /.nuxt/router.scrollBehavior.js | ||||||
|  | /.nuxt/routes.json | ||||||
|  | /.nuxt/server.js | ||||||
|  | /.nuxt/store.js | ||||||
|  | /.nuxt/utils.js | ||||||
|   | |||||||
							
								
								
									
										99
									
								
								bin/build.js
									
									
									
									
									
								
							
							
						
						
									
										99
									
								
								bin/build.js
									
									
									
									
									
								
							| @@ -1,99 +0,0 @@ | |||||||
| const axios = require('axios') |  | ||||||
| const {fsExtra, copyFiles, findApp, chalkTag, fs} = require("./tools"); |  | ||||||
| const compiler = require('vue-template-compiler') |  | ||||||
| const getBuildConfig = id => { |  | ||||||
|   axios.post('http://192.168.1.87:12525/node/custom/detail', null, {params: {id}}).then(res => { |  | ||||||
|     if (res?.data) { |  | ||||||
|       const config = res.data.data |  | ||||||
|       fsExtra.outputJson('src/config.json', config.extra) |  | ||||||
|       createPages(config) |  | ||||||
|     } |  | ||||||
|   }) |  | ||||||
| } |  | ||||||
| const getAppInfo = (file, apps) => { |  | ||||||
|   if (/[\\\/](App[A-Z][^\\\/]+)\.vue$/g.test(file)) { |  | ||||||
|     const name = file.replace(/.+[\\\/](App[^\\\/]+)\.vue$/, '$1'), |  | ||||||
|       source = fs.readFileSync(file).toString(), |  | ||||||
|       parsed = compiler.parseComponent(source), |  | ||||||
|       script = parsed.script?.content || "", |  | ||||||
|       label = script.match(/label:[^,]+/)?.[0]?.replace(/.+["']([^"']+).+/, '$1') |  | ||||||
|     const paths = file.split(/[\\\/]/) |  | ||||||
|     apps.push({ |  | ||||||
|       id: file.replace(/\.vue$/, '').replace(/[\\\/]/g, '_'), |  | ||||||
|       label: label || name, |  | ||||||
|       path: `/${file.replace(/\.vue$/, '').replace(/[\\\/]/g, '/')}`, |  | ||||||
|       workspace: paths.at(0), |  | ||||||
|       esm: file.replace(/[\\\/]/g, '/').substring(4), |  | ||||||
|       name |  | ||||||
|     }) |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * 根据配置生成应用路由 |  | ||||||
|  * @param {Object} config - 配置对象,用于定制化路由生成过程 |  | ||||||
|  * @returns {Promise} - 返回一个Promise对象,表示路由生成完成 |  | ||||||
|  */ |  | ||||||
| const createRoutes = (config = {}) => { |  | ||||||
|   // 初始化路由数组 |  | ||||||
|   const routes = [] |  | ||||||
|   // 获取签到页面的路径,如果未指定,则使用默认路径 |  | ||||||
|   let signPage = '../views/sign' |  | ||||||
|   let {signPage: sign, homePage: home = "console"} = config.extra || {} |  | ||||||
|   if (config.extra?.signPage) { |  | ||||||
|     signPage = `../apps/custom/${sign}/${sign}` |  | ||||||
|   } |  | ||||||
|   let homePage = `../views/console` |  | ||||||
|   if (config.extra?.homePage) { |  | ||||||
|     homePage = `../apps/custom/${home}/${home}` |  | ||||||
|   } |  | ||||||
|   // 查找并处理所有应用,将它们的信息添加到路由中 |  | ||||||
|   return findApp("src/apps", app => getAppInfo(app, routes)).then(() => { |  | ||||||
|     // 生成并输出apps.js文件,定义所有应用的路由 |  | ||||||
|     fsExtra.outputFile('src/utils/apps.js', `export default [ |  | ||||||
|     {path: "/login", name: "登录", component: () => import('${signPage}')}, |  | ||||||
|     {path: '/dv', name: '数据大屏入口', component: () => import('../views/dvIndex')}, |  | ||||||
|     {path: '/v', name: 'Home', component: () => import('../views/home'), children: [ |  | ||||||
|       {path:'/',name:'mainEntry', component:()=>import('../views/mainEntry'),children:[ |  | ||||||
|       {name: "${home}", path: "${home}", component: () => import('${homePage}')}, |  | ||||||
|       ${routes.filter(e => ![sign, home].includes(e.name)).map(e => { |  | ||||||
|       // 解构每个路由的属性,用于生成路由配置 |  | ||||||
|       const {name, label, esm} = e |  | ||||||
|       // 生成单个路由配置的字符串表示 |  | ||||||
|       return `{name:"${name}",label:"${label}",path:"${name}",component:()=>import("../${esm}")}` |  | ||||||
|     }).join(',\n')}, |  | ||||||
|       {path: '*',name: '404',component: ()=>import('../views/building')}, |  | ||||||
|       ]} |  | ||||||
|     ]}, |  | ||||||
|     {path: '/', name: "init"}, |  | ||||||
|      |  | ||||||
|     ]`) |  | ||||||
|     // 扫描完毕,使用chalkTag标记任务完成 |  | ||||||
|     chalkTag.done("扫描完毕") |  | ||||||
|   }) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const createPages = (config = {}) => { |  | ||||||
|   fsExtra.emptyDir("src/apps", err => { |  | ||||||
|     if (!err) { |  | ||||||
|       const {customPath, appList} = config |  | ||||||
|       const stdApps = {} |  | ||||||
|       appList.filter(e => !/project/.test(e.id))?.forEach(e => { |  | ||||||
|         const paths = e.libPath.split('/').filter(Boolean) || [] |  | ||||||
|         paths.pop() |  | ||||||
|         stdApps[paths.join("/")] = 1 |  | ||||||
|       }) |  | ||||||
|       Promise.all([ |  | ||||||
|         copyFiles("src/apps/core", "packages/core"), |  | ||||||
|         copyFiles("src/apps/custom", `project/${customPath}`), |  | ||||||
|         ...Object.keys(stdApps).map(e => copyFiles(`src/apps/${e.replace(/^packages[\\\/]/, '')}`, e)), |  | ||||||
|       ]).then(() => createRoutes(config)).then(() => fsExtra.ensureFile("src/apps/actions.js")) |  | ||||||
|     } |  | ||||||
|   }) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const start = () => { |  | ||||||
|   const buildId = process.argv[2] || process.env.VUE_APP_OMS_ID || 'f670cc46-7cf7-4a0f-86ee-3077044c0b17' |  | ||||||
|   getBuildConfig(buildId) |  | ||||||
| } |  | ||||||
| start() |  | ||||||
							
								
								
									
										33
									
								
								bin/mods.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								bin/mods.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | |||||||
|  | const {chalkTag, findApp, fs, fsExtra} = require("./tools"); | ||||||
|  | const compiler = require('vue-template-compiler') | ||||||
|  | const getAppInfo = (file, apps) => { | ||||||
|  |   if (/[\\\/](App[A-Z][^\\\/]+)\.vue$/g.test(file)) { | ||||||
|  |     const name = file.replace(/.+[\\\/](App[^\\\/]+)\.vue$/, '$1'), | ||||||
|  |         source = fs.readFileSync(file).toString(), | ||||||
|  |         parsed = compiler.parseComponent(source), | ||||||
|  |         script = parsed.script?.content || "", | ||||||
|  |         label = script.match(/label:[^,]+/)?.[0]?.replace(/.+["']([^"']+).+/, '$1') | ||||||
|  |     const paths = file.split(/[\\\/]/) | ||||||
|  |     apps.push({ | ||||||
|  |       id: file.replace(/\.vue$/, '').replace(/[\\\/]/g, '_'), | ||||||
|  |       label: label || name, | ||||||
|  |       path: `/${file.replace(/\.vue$/, '').replace(/[\\\/]/g, '/')}`, | ||||||
|  |       workspace: paths.at(0), | ||||||
|  |       esm: ['.', paths.slice(1)].flat().join("/"), | ||||||
|  |       name | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const start = () => { | ||||||
|  |   chalkTag.info("开始扫描库工程...") | ||||||
|  |   const list = [] | ||||||
|  |   Promise.all([ | ||||||
|  |     findApp('packages', app => getAppInfo(app, list)), | ||||||
|  |     findApp('project', app => getAppInfo(app, list)), | ||||||
|  |   ]).then(() => { | ||||||
|  |     fsExtra.outputJson('examples/modules.json', {apps: list}) | ||||||
|  |     chalkTag.done("扫描完毕") | ||||||
|  |   }) | ||||||
|  | } | ||||||
|  | start() | ||||||
| @@ -1,37 +0,0 @@ | |||||||
| const {chalkTag, findApp, fs, fsExtra} = require("./tools"); |  | ||||||
| const compiler = require('vue-template-compiler') |  | ||||||
| const getAppInfo = (file, apps) => { |  | ||||||
|   if (/[\\\/](App[A-Z][^\\\/]+)\.vue$/g.test(file)) { |  | ||||||
|     const name = file.replace(/.+[\\\/](App[^\\\/]+)\.vue$/, '$1'), |  | ||||||
|       source = fs.readFileSync(file).toString(), |  | ||||||
|       parsed = compiler.parseComponent(source), |  | ||||||
|       script = parsed.script?.content || "", |  | ||||||
|       label = script.match(/label:[^,]+/)?.[0]?.replace(/.+["']([^"']+).+/, '$1') |  | ||||||
|     const paths = file.split(/[\\\/]/) |  | ||||||
|     apps.push({ |  | ||||||
|       id: file.replace(/\.vue$/, '').replace(/[\\\/]/g, '_'), |  | ||||||
|       label: label || name, |  | ||||||
|       path: `/${file.replace(/\.vue$/, '').replace(/[\\\/]/g, '/')}`, |  | ||||||
|       workspace: paths.at(0), |  | ||||||
|       esm: file.replace(/[\\\/]/g, '/'), |  | ||||||
|       name |  | ||||||
|     }) |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const start = () => { |  | ||||||
|   chalkTag.info("开始扫描库工程...") |  | ||||||
|   const {VUE_APP_SCOPE, VUE_APP_CORE} = process.env |  | ||||||
|   const list = [] |  | ||||||
|   let scanScope = ['packages', 'project'] |  | ||||||
|   if (VUE_APP_SCOPE) scanScope = [`project/${VUE_APP_SCOPE}`] |  | ||||||
|   if (VUE_APP_CORE) scanScope.push('packages/core') |  | ||||||
|   Promise.all(scanScope.map(e => findApp(e, app => getAppInfo(app, list)))).then(() => { |  | ||||||
|     fsExtra.outputFile('examples/router/apps.js', `export default [${list.map(e => { |  | ||||||
|       const {name, label, path, esm} = e |  | ||||||
|       return `{name:"${name}",label:"${label}",path:"${path}",component:()=>import("@${esm}")}` |  | ||||||
|     }).join(',\n')}]`) |  | ||||||
|     chalkTag.done("扫描完毕") |  | ||||||
|   }) |  | ||||||
| } |  | ||||||
| start() |  | ||||||
| @@ -1,8 +1,8 @@ | |||||||
| <template> | <template> | ||||||
|   <section class="mainContent"> |   <section class="mainContent"> | ||||||
|     <ai-nav-tab :routes="$apps"/> |     <ai-nav-tab :routes="apps"/> | ||||||
|     <div class="fill"> |     <div class="fill"> | ||||||
|       <router-view v-bind="$attrs.commonAttrs"/> |       <router-view/> | ||||||
|       <ai-empty v-if="isHome">欢迎使用村微产品库</ai-empty> |       <ai-empty v-if="isHome">欢迎使用村微产品库</ai-empty> | ||||||
|     </div> |     </div> | ||||||
|   </section> |   </section> | ||||||
| @@ -10,11 +10,13 @@ | |||||||
|  |  | ||||||
| <script> | <script> | ||||||
| import AiNavTab from "dui/packages/basic/AiNavTab"; | import AiNavTab from "dui/packages/basic/AiNavTab"; | ||||||
|  | import {mapState} from "vuex" | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   name: "mainContent", |   name: "mainContent", | ||||||
|   components: {AiNavTab}, |   components: {AiNavTab}, | ||||||
|   computed: { |   computed: { | ||||||
|  |     ...mapState(['apps']), | ||||||
|     isHome: v => v.$route.path == '/', |     isHome: v => v.$route.path == '/', | ||||||
|   }, |   }, | ||||||
| } | } | ||||||
|   | |||||||
| @@ -39,10 +39,10 @@ export default { | |||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   computed: { |   computed: { | ||||||
|     ...mapState(['user']), |     ...mapState(['user', 'apps']), | ||||||
|     navs() { |     navs() { | ||||||
|       let reg = new RegExp(`.*${this.searchApp?.replace(/-/g,'')||''}.*`, 'gi') |       let reg = new RegExp(`.*${this.searchApp?.replace(/-/g,'')||''}.*`, 'gi') | ||||||
|       return (this.$apps || []).filter(e => !this.searchApp || reg?.test(e.name) || reg?.test(e.label)).map(e => { |       return (this.apps || []).filter(e => !this.searchApp || reg?.test(e.name) || reg?.test(e.label)).map(e => { | ||||||
|         if (/\/project\//.test(e.path)) { |         if (/\/project\//.test(e.path)) { | ||||||
|           e.project = process.env.VUE_APP_SCOPE || e.path.replace(/.*project\/([^\/]+)\/.+/, '$1') |           e.project = process.env.VUE_APP_SCOPE || e.path.replace(/.*project\/([^\/]+)\/.+/, '$1') | ||||||
|         } else if (/\/core\//.test(e.path)) { |         } else if (/\/core\//.test(e.path)) { | ||||||
| @@ -52,9 +52,9 @@ export default { | |||||||
|       }) |       }) | ||||||
|     }, |     }, | ||||||
|     menuPath() { |     menuPath() { | ||||||
|       let paths = [], current = this.$apps?.find(e => e.name == this.$route.name) |       let paths = [], current = this.apps?.find(e => e.name == this.$route.name) | ||||||
|       const findParent = name => { |       const findParent = name => { | ||||||
|         let menu = this.$apps?.find(e => e.name == name) |         let menu = this.apps?.find(e => e.name == name) | ||||||
|         if (menu) { |         if (menu) { | ||||||
|           paths.push(menu.name) |           paths.push(menu.name) | ||||||
|           if (!!menu.parentId) findParent(menu.parentId) |           if (!!menu.parentId) findParent(menu.parentId) | ||||||
| @@ -102,7 +102,7 @@ export default { | |||||||
|       localStorage.setItem("searchApp", this.searchApp) |       localStorage.setItem("searchApp", this.searchApp) | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|   created() { |   mounted() { | ||||||
|     this.searchApp = localStorage.getItem("searchApp") || "" |     this.searchApp = localStorage.getItem("searchApp") || "" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,18 +1,14 @@ | |||||||
| import Vue from 'vue'; | import Vue from 'vue'; | ||||||
| import App from './App.vue'; | import App from './App.vue'; | ||||||
| import ui from 'element-ui'; | import router from './router/router'; | ||||||
| import router from './router'; |  | ||||||
| import axios from './router/axios'; | import axios from './router/axios'; | ||||||
| import utils from './utils'; | import utils from './utils'; | ||||||
| import dui from 'dui/packages'; | import dui from 'dui'; | ||||||
| import store from './store'; | import store from './store'; | ||||||
| import dataV from '@jiaminghi/data-view'; | import dataV from '@jiaminghi/data-view'; | ||||||
| import dvui from 'dui/dv' |  | ||||||
|  |  | ||||||
| Vue.use(dataV) | Vue.use(dataV) | ||||||
| Vue.use(ui); |  | ||||||
| Vue.use(dui); | Vue.use(dui); | ||||||
| Vue.use(dvui); |  | ||||||
| //富文本编辑器配置 | //富文本编辑器配置 | ||||||
| Vue.config.productionTip = false; | Vue.config.productionTip = false; | ||||||
| Object.keys(utils).map((e) => (Vue.prototype[e] = utils[e])); | Object.keys(utils).map((e) => (Vue.prototype[e] = utils[e])); | ||||||
| @@ -22,14 +18,12 @@ const app = new Vue({ | |||||||
|   store, |   store, | ||||||
|   render: h => h(App) |   render: h => h(App) | ||||||
| }); | }); | ||||||
|  |  | ||||||
| let theme = null | let theme = null | ||||||
| store.dispatch('getSystem').then(res => { | store.dispatch('getSystem').then(res => { | ||||||
|   theme = JSON.parse(res?.colorScheme || null) |   theme = JSON.parse(res?.colorScheme || null) | ||||||
|   Vue.prototype.$theme = theme?.web || "blue" |   Vue.prototype.$theme = theme?.web || "blue" | ||||||
|   return import(`dui/lib/styles/theme.${theme?.web}.scss`).catch(() => 0) |   return import(`dui/lib/styles/theme.${theme?.web}.scss`).catch(() => 0) | ||||||
| }).finally(() => { | }).finally(() => { | ||||||
|   Vue.prototype.$vm = app |  | ||||||
|   import(`dui/lib/styles/common.scss`).finally(() => app.$mount('#app')) |   import(`dui/lib/styles/common.scss`).finally(() => app.$mount('#app')) | ||||||
| }) | }) | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										21
									
								
								examples/nuxt.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								examples/nuxt.config.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | import {resolve} from 'path' | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   css: ['ui/lib/styles/common.scss'], | ||||||
|  |   dev: process.env.NODE_ENV !== 'production', | ||||||
|  |   alias: { | ||||||
|  |     'style': resolve(__dirname, './assets/style'), | ||||||
|  |     'dui': resolve(__dirname, '../ui') | ||||||
|  |   }, | ||||||
|  |   srcDir: "examples", | ||||||
|  |   dir: { | ||||||
|  |     pages: 'views', | ||||||
|  |   }, | ||||||
|  |   build: { | ||||||
|  |     postcss: null, | ||||||
|  |     transpile: [/^ui/] | ||||||
|  |   }, | ||||||
|  |   plugins: [ | ||||||
|  |     '~plugins/ui.js' | ||||||
|  |   ], | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								examples/plugins/ui.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								examples/plugins/ui.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | import Vue from 'vue'; | ||||||
|  | import ElementUI from 'element-ui'; | ||||||
|  | import dui from 'dui/packages'; | ||||||
|  | import 'dui/lib/styles/common.scss'; | ||||||
|  |  | ||||||
|  | Vue.use(ElementUI); | ||||||
|  | Vue.use(dui) | ||||||
							
								
								
									
										81
									
								
								examples/router/autoRoutes.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								examples/router/autoRoutes.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | |||||||
|  | import store from "../store"; | ||||||
|  | import {waiting} from "../utils"; | ||||||
|  | import appEntry from "../views/appEntry"; | ||||||
|  | import router from "./router"; | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   routes: () => store.state.apps, | ||||||
|  |   init() { | ||||||
|  |     //约束正则式 | ||||||
|  |     store.commit("cleanApps") | ||||||
|  |     // 自动化本工程应用 | ||||||
|  |     waiting.init({innerHTML: '应用加载中..'}) | ||||||
|  |     let startTime = new Date().getTime() | ||||||
|  |     /** | ||||||
|  |      * require.context 的路径变量范式只能为静态字符串 | ||||||
|  |      */ | ||||||
|  |     switch (process.env.VUE_APP_SCOPE) { | ||||||
|  |       case 'dv': | ||||||
|  |         this.esm = { | ||||||
|  |           packages: require.context('../../packages/bigscreen', true, /\.(\/.+)\/App[A-Z][^\/]+\.vue$/, 'lazy') | ||||||
|  |         } | ||||||
|  |         break | ||||||
|  |       case 'fengdu': | ||||||
|  |         this.esm = { | ||||||
|  |           project: require.context('../../project/fengdu', true, /\.(\/.+)\/App[A-Z][^\/]+\.vue$/, 'lazy') | ||||||
|  |         } | ||||||
|  |         break | ||||||
|  |       case 'ai': | ||||||
|  |         this.esm = { | ||||||
|  |           biaopin: require.context('../../project/biaopin/AppCopilotConfig', true, /\.\/App[A-Z][^\/]+\.vue$/, 'lazy'), | ||||||
|  |           project: require.context('../../project/ai', true, /\.(\/.+)\/App[A-Z][^\/]+\.vue$/, 'lazy') | ||||||
|  |         } | ||||||
|  |         break | ||||||
|  |       case 'oms': | ||||||
|  |         this.esm = { | ||||||
|  |           project: require.context('../../project/oms', true, /\.(\/.+)\/App[A-Z][^\/]+\.vue$/, 'lazy') | ||||||
|  |         } | ||||||
|  |         break | ||||||
|  |       default: | ||||||
|  |         this.esm = { | ||||||
|  |           packages: require.context('../../packages/', true, /\.(\/.+)\/App[A-Z][^\/]+\.vue$/, 'lazy'), | ||||||
|  |           project: require.context('../../project/', true, /\.(\/.+)\/App[A-Z][^\/]+\.vue$/, 'lazy') | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     console.log('模块引用用了%s秒', (new Date().getTime() - startTime) / 1000) | ||||||
|  |     startTime = new Date().getTime() | ||||||
|  |     this.loadApps().finally(() => { | ||||||
|  |       console.log('模块加载用了%s秒', (new Date().getTime() - startTime) / 1000) | ||||||
|  |       waiting.close() | ||||||
|  |     }) | ||||||
|  |   }, | ||||||
|  |   loadMods() { | ||||||
|  |     // return Promise.all(mods.apps.map(e => { | ||||||
|  |     //   Vue.component(e.name, this.esm[e.workspace](e.esm)) | ||||||
|  |     //   const addApp = {...e, component: appEntry} | ||||||
|  |     //   waiting.setContent(`加载${e.name}...`) | ||||||
|  |     //   //命名规范入口文件必须以App开头 | ||||||
|  |     //   return store.commit("addApp", addApp) | ||||||
|  |     // })) | ||||||
|  |   }, | ||||||
|  |   loadApps() { | ||||||
|  |     //新App的自动化格式 | ||||||
|  |     const promise = (mods, base) => Promise.all(mods.keys().map(path => mods(path).then(file => { | ||||||
|  |       if (file.default) { | ||||||
|  |         const {name, label} = file.default | ||||||
|  |         const addApp = { | ||||||
|  |           name: [base, path.replace(/\.\/?(vue)?/g, '')?.split("/")].flat().join("_"), | ||||||
|  |           label: label || name, | ||||||
|  |           path: `/${base}${path.replace(/\.(\/.+\/App.+)\.vue$/, '$1')}`, | ||||||
|  |           component: appEntry, | ||||||
|  |           esm: file.default | ||||||
|  |         } | ||||||
|  |         waiting.setContent(`加载${name}...`) | ||||||
|  |         router.addRoute(addApp) | ||||||
|  |         //命名规范入口文件必须以App开头 | ||||||
|  |         return store.commit("addApp", addApp) | ||||||
|  |       } else return 0 | ||||||
|  |     }).catch(err => console.log(err)))) | ||||||
|  |     return Promise.all(Object.entries(this.esm).map(([root, mods]) => promise(mods, root))).catch(console.error) | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| import { Message } from 'element-ui' | import {Message} from 'element-ui' | ||||||
| import instance from 'dui/lib/js/request' | import instance from '../../ui/lib/js/request' | ||||||
|  |  | ||||||
| let baseURLs = { | let baseURLs = { | ||||||
|   production: "/", |   production: "/", | ||||||
| @@ -8,10 +8,34 @@ let baseURLs = { | |||||||
| instance.defaults.baseURL = baseURLs[process.env.NODE_ENV] | instance.defaults.baseURL = baseURLs[process.env.NODE_ENV] | ||||||
| instance.interceptors.request.use(config => { | instance.interceptors.request.use(config => { | ||||||
|   if (config.url.startsWith("/node")) { |   if (config.url.startsWith("/node")) { | ||||||
|     config.url = "/ns" + config.url |     config.baseURL = "/ns" | ||||||
|  |   } else if (config.url.startsWith("/sse")) { | ||||||
|  |     config.baseURL = "/" | ||||||
|  |   } else if (/\/project\/activeAnalysis/.test(location.pathname)) { | ||||||
|  |     config.baseURL = "/analysis" | ||||||
|  |   } else if (/\/project\/beta/.test(location.pathname)) { | ||||||
|  |     config.baseURL = "/wg" | ||||||
|  |   } else if (/\/project\/sass/.test(location.pathname)) { | ||||||
|  |     config.baseURL = "/saas" | ||||||
|  |   } else if (/\/tianfuxing/.test(location.pathname)) { | ||||||
|  |     config.baseURL = "/tfx" | ||||||
|  |   } else if (/\/qianxinan/.test(location.pathname)) { | ||||||
|  |     // config.baseURL = "/qxn" | ||||||
|  |   } else if (/\/xiushan/.test(location.pathname)) { | ||||||
|  |     config.baseURL = "/xsjr" | ||||||
|  |   } else if (/project\/oms/.test(location.pathname)) { | ||||||
|  |     config.baseURL = "/omsapi" | ||||||
|  |   } else if (/#url-/.test(location.hash)) { | ||||||
|  |     config.baseURL = location.hash.replace(/#url-/, '/') | ||||||
|  |   } | ||||||
|  |   if (["/xsjr", "/tfx", "/omsapi"].includes(config.baseURL)) { | ||||||
|  |     config.url = config.url.replace(/(app|auth|admin|api)\//, "api/") | ||||||
|  |   } | ||||||
|  |   if (['/qxn', '/analysis'].includes(config.baseURL)) { | ||||||
|  |     config.url = config.url.replace(/(app|auth|admin)\//, "api/") | ||||||
|   } |   } | ||||||
|   if (process.env.VUE_APP_IS_SIMPLE_SERVER == 1) { |   if (process.env.VUE_APP_IS_SIMPLE_SERVER == 1) { | ||||||
|     config.url = config.url.replace(/^\/(app|auth|admin)\//, "/api/") |     config.url = config.url.replace(/(app|auth|admin)\//, "api/") | ||||||
|   } |   } | ||||||
|   return config |   return config | ||||||
| }, error => Message.error(error)) | }, error => Message.error(error)) | ||||||
|   | |||||||
| @@ -1,13 +1,13 @@ | |||||||
| import Vue from 'vue' | import Vue from 'vue' | ||||||
| import VueRouter from 'vue-router' | import VueRouter from 'vue-router' | ||||||
| import apps from "./apps"; | import autoRoutes from './autoRoutes' | ||||||
| 
 | 
 | ||||||
| Vue.use(VueRouter) | Vue.use(VueRouter) | ||||||
| Vue.prototype.$apps = apps | autoRoutes.init() | ||||||
| export default new VueRouter({ | export default new VueRouter({ | ||||||
|   mode: 'history', |   mode: 'history', | ||||||
|   hashbang: false, |   hashbang: false, | ||||||
|   routes: apps, |   routes: autoRoutes.routes(), | ||||||
|   scrollBehavior(to) { |   scrollBehavior(to) { | ||||||
|     if (to.hash) { |     if (to.hash) { | ||||||
|       return { |       return { | ||||||
| @@ -1,12 +1,26 @@ | |||||||
| import Vue from 'vue' | import Vue from 'vue' | ||||||
| import Vuex from 'vuex' | import Vuex from 'vuex' | ||||||
| import preState from 'vuex-persistedstate' |  | ||||||
| import * as modules from "dui/lib/js/modules" | import * as modules from "dui/lib/js/modules" | ||||||
| import xsActions from "../../project/xiushan/actions" | import xsActions from "../../project/xiushan/actions" | ||||||
|  |  | ||||||
| Vue.use(Vuex) | Vue.use(Vuex) | ||||||
| export default new Vuex.Store({ | export const state = () => ({ | ||||||
|   actions: {...xsActions}, |   apps: [] | ||||||
|   modules, |  | ||||||
|   plugins: [preState()] |  | ||||||
| }) | }) | ||||||
|  | export const mutations = { | ||||||
|  |   addApp(state, app) { | ||||||
|  |     state.apps.push(app) | ||||||
|  |   }, | ||||||
|  |   cleanApps(state) { | ||||||
|  |     state.apps = [] | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const actions = { | ||||||
|  |   ...xsActions | ||||||
|  | } | ||||||
|  | export default { | ||||||
|  |   state, | ||||||
|  |   mutations, | ||||||
|  |   actions, | ||||||
|  |   modules, | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										36
									
								
								examples/views/appEntry.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								examples/views/appEntry.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="appEntry"> | ||||||
|  |     <component v-if="app" :is="app" ref="currentPage" :instance="$request" :dict="$dict" :permissions="$permissions"/> | ||||||
|  |     <ai-empty v-else>无法找到应用文件</ai-empty> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import {mapState} from "vuex"; | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   name: "appEntry", | ||||||
|  |   label: "应用库-应用", | ||||||
|  |   computed: { | ||||||
|  |     ...mapState(['apps']), | ||||||
|  |     app() { | ||||||
|  |       const app = this.apps.find(e => e.name == this.$route.name) | ||||||
|  |       return app.esm ?? "" | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .appEntry { | ||||||
|  |   width: 100%; | ||||||
|  |   flex: 1; | ||||||
|  |   min-width: 0; | ||||||
|  |   min-height: 0; | ||||||
|  |   height: 100%; | ||||||
|  |  | ||||||
|  |   & > * { | ||||||
|  |     height: 100%; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @@ -9,13 +9,13 @@ | |||||||
|       </template> |       </template> | ||||||
|     </header-nav> |     </header-nav> | ||||||
|     <ai-dv-wrapper class="fill" v-if="dvDev"> |     <ai-dv-wrapper class="fill" v-if="dvDev"> | ||||||
|       <router-view v-bind="commonAttrs"/> |       <router-view/> | ||||||
|     </ai-dv-wrapper> |     </ai-dv-wrapper> | ||||||
|     <el-row v-else-if="showTools" class="fill mar-t48" type="flex"> |     <el-row v-else-if="showTools" class="fill mar-t48" type="flex"> | ||||||
|       <slider-nav/> |       <slider-nav/> | ||||||
|       <main-content class="fill" :commonAttrs="commonAttrs"/> |       <main-content class="fill"/> | ||||||
|     </el-row> |     </el-row> | ||||||
|     <router-view class="fill" v-else v-bind="commonAttrs"/> |     <router-view class="fill" v-else/> | ||||||
|     <div v-if="dialog" class="sign-box"> |     <div v-if="dialog" class="sign-box"> | ||||||
|       <ai-sign style="margin: auto" :instance="$request" :action="{login}" |       <ai-sign style="margin: auto" :instance="$request" :action="{login}" | ||||||
|                visible @login="getToken" :showScanLogin="false"/> |                visible @login="getToken" :showScanLogin="false"/> | ||||||
| @@ -25,16 +25,15 @@ | |||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script> | <script> | ||||||
| import SliderNav from "./components/sliderNav"; | import SliderNav from "../components/sliderNav"; | ||||||
| import MainContent from "./components/mainContent"; | import MainContent from "../components/mainContent"; | ||||||
| import HeaderNav from "./components/headerNav"; | import HeaderNav from "../components/headerNav"; | ||||||
| import {mapActions, mapMutations, mapState} from "vuex"; | import {mapActions, mapMutations, mapState} from "vuex"; | ||||||
| import Mock from "./components/mock"; | import Mock from "../components/mock"; | ||||||
| import AiDvWrapper from "dui/dv/layout/AiDvWrapper/AiDvWrapper.vue"; |  | ||||||
| 
 | 
 | ||||||
| export default { | export default { | ||||||
|   name: 'app', |   name: 'app', | ||||||
|   components: {AiDvWrapper, Mock, HeaderNav, MainContent, SliderNav}, |   components: {Mock, HeaderNav, MainContent, SliderNav}, | ||||||
|   computed: { |   computed: { | ||||||
|     ...mapState(['user']), |     ...mapState(['user']), | ||||||
|     login() { |     login() { | ||||||
| @@ -42,13 +41,6 @@ export default { | |||||||
|       /project\/sass/g.test(location.pathname) && (url += "?corpId=ww596787bb70f08288") |       /project\/sass/g.test(location.pathname) && (url += "?corpId=ww596787bb70f08288") | ||||||
|       return url |       return url | ||||||
|     }, |     }, | ||||||
|     commonAttrs() { |  | ||||||
|       return { |  | ||||||
|         instance: this.$request, |  | ||||||
|         dict: this.$dict, |  | ||||||
|         permissions: this.$permissions |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   }, |   }, | ||||||
|   data() { |   data() { | ||||||
|     return { |     return { | ||||||
| @@ -82,7 +74,7 @@ export default { | |||||||
|     handleMock() { |     handleMock() { | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   created() { |   mounted() { | ||||||
|     const {jWeixin} = window |     const {jWeixin} = window | ||||||
|     window.wx = jWeixin |     window.wx = jWeixin | ||||||
|     if (this.user.token) this.getUserInfo().finally(() => { |     if (this.user.token) this.getUserInfo().finally(() => { | ||||||
							
								
								
									
										33
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,20 +1,19 @@ | |||||||
| { | { | ||||||
|   "name": "dvcp-web-apps", |   "name": "dvcp-web", | ||||||
|   "version": "4.0.0", |   "version": "4.0.0", | ||||||
|   "private": false, |   "private": false, | ||||||
|   "author": "kubbo", |   "author": "kubbo", | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "dev": "vue-cli-service serve examples/main.js", |     "dev": "nuxt -c examples/nuxt.config.js", | ||||||
|     "build": "vue-cli-service build", |     "build": "vue-cli-service build", | ||||||
|     "oms": "vue-cli-service serve examples/main.js --mode oms", |     "dev:ai": "vue-cli-service serve examples/main.js --mode ai", | ||||||
|     "xumu": "vue-cli-service serve examples/main.js --mode xumu", |     "dev:oms": "vue-cli-service serve examples/main.js --mode oms", | ||||||
|  |     "dev:biaopin": "vue-cli-service serve examples/main.js --mode biaopin", | ||||||
|  |     "dev:dv": "vue-cli-service serve examples/main.js --mode dv", | ||||||
|  |     "dev:fengdu": "vue-cli-service serve examples/main.js --mode fengdu", | ||||||
|     "sync": "node bin/appsSync.js", |     "sync": "node bin/appsSync.js", | ||||||
|     "preview": "node bin/build.js && vue-cli-service serve", |     "preview": "vue-cli-service serve", | ||||||
|     "predev": "node bin/scanApps.js", |     "prebuild": "" | ||||||
|     "preoms": "dotenv -e .env.oms node bin/scanApps.js", |  | ||||||
|     "prexumu": "dotenv -e .env.xumu node bin/scanApps.js", |  | ||||||
|     "view:xumu": "vue-cli-service serve --mode xumu", |  | ||||||
|     "preview:xumu": "dotenv -e .env.xumu node bin/build.js" |  | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@amap/amap-jsapi-loader": "^1.0.1", |     "@amap/amap-jsapi-loader": "^1.0.1", | ||||||
| @@ -22,13 +21,11 @@ | |||||||
|     "@jiaminghi/data-view": "^2.10.0", |     "@jiaminghi/data-view": "^2.10.0", | ||||||
|     "@logicflow/core": "^1.2.1", |     "@logicflow/core": "^1.2.1", | ||||||
|     "bin-ace-editor": "^3.2.0", |     "bin-ace-editor": "^3.2.0", | ||||||
|     "crypto-js": "^4.2.0", |     "crypto-js": "^4.1.1", | ||||||
|     "dayjs": "^1.8.35", |     "dayjs": "^1.8.35", | ||||||
|     "echarts": "^5.5.1", |  | ||||||
|     "echarts-wordcloud": "^2.0.0", |     "echarts-wordcloud": "^2.0.0", | ||||||
|     "hash.js": "^1.1.7", |     "hash.js": "^1.1.7", | ||||||
|     "html2canvas": "^1.4.1", |     "html2canvas": "^1.4.1", | ||||||
|     "jspdf": "^2.5.2", |  | ||||||
|     "mp4box": "^0.4.1", |     "mp4box": "^0.4.1", | ||||||
|     "print-js": "^1.0.63", |     "print-js": "^1.0.63", | ||||||
|     "serialize-javascript": "^6.0.0", |     "serialize-javascript": "^6.0.0", | ||||||
| @@ -51,7 +48,6 @@ | |||||||
|     "axios": "^0.19.2", |     "axios": "^0.19.2", | ||||||
|     "babel-eslint": "^10.1.0", |     "babel-eslint": "^10.1.0", | ||||||
|     "core-js": "^2.6.11", |     "core-js": "^2.6.11", | ||||||
|     "dotenv-cli": "^7.4.2", |  | ||||||
|     "element-ui": "^2.15.9", |     "element-ui": "^2.15.9", | ||||||
|     "eslint": "^5.16.0", |     "eslint": "^5.16.0", | ||||||
|     "eslint-plugin-vue": "^5.0.0", |     "eslint-plugin-vue": "^5.0.0", | ||||||
| @@ -59,6 +55,7 @@ | |||||||
|     "inquirer": "^6.5.2", |     "inquirer": "^6.5.2", | ||||||
|     "mockjs": "^1.1.0", |     "mockjs": "^1.1.0", | ||||||
|     "node-ipc": "^9.2.1", |     "node-ipc": "^9.2.1", | ||||||
|  |     "nuxt": "^2.18.1", | ||||||
|     "readline": "^1.3.0", |     "readline": "^1.3.0", | ||||||
|     "sass": "~1.32.6", |     "sass": "~1.32.6", | ||||||
|     "sass-loader": "^7.3.1", |     "sass-loader": "^7.3.1", | ||||||
| @@ -69,14 +66,6 @@ | |||||||
|     "vuex": "^3.5.1", |     "vuex": "^3.5.1", | ||||||
|     "vuex-persistedstate": "^2.7.1" |     "vuex-persistedstate": "^2.7.1" | ||||||
|   }, |   }, | ||||||
|   "vetur": { |  | ||||||
|     "attributes": "./attributes.json" |  | ||||||
|   }, |  | ||||||
|   "postcss": { |  | ||||||
|     "plugins": { |  | ||||||
|       "autoprefixer": {} |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   "browserslist": [ |   "browserslist": [ | ||||||
|     "> 1%", |     "> 1%", | ||||||
|     "last 2 versions", |     "last 2 versions", | ||||||
|   | |||||||
| @@ -168,7 +168,7 @@ import {monitorTypes} from "../config"; | |||||||
| import ConfigItem from "./configItem.vue"; | import ConfigItem from "./configItem.vue"; | ||||||
| import DatasourcePicker from "./datasourcePicker.vue"; | import DatasourcePicker from "./datasourcePicker.vue"; | ||||||
| import AiSelect from "dui/packages/basic/AiSelect.vue"; | import AiSelect from "dui/packages/basic/AiSelect.vue"; | ||||||
| import {DvCompData} from "dui/dv"; | import {DvCompData} from "@dui/dv"; | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   name: 'dataConfig', |   name: 'dataConfig', | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ import ConfigItem from "./configItem"; | |||||||
| import ChartPicker from "./chartPicker"; | import ChartPicker from "./chartPicker"; | ||||||
| import JsonEditor from "./jsonEditor"; | import JsonEditor from "./jsonEditor"; | ||||||
| import {layers, monitorTypes} from "../config"; | import {layers, monitorTypes} from "../config"; | ||||||
| import AiDvSummary from "dui/dv/layout/AiDvSummary/AiDvSummary"; | import AiDvSummary from "@dui/dv/layout/AiDvSummary/AiDvSummary"; | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   name: "configExtra", |   name: "configExtra", | ||||||
|   | |||||||
| @@ -34,7 +34,7 @@ import 'brace/snippets/json'; | |||||||
| import 'brace/theme/github'; | import 'brace/theme/github'; | ||||||
| import 'brace/theme/monokai'; | import 'brace/theme/monokai'; | ||||||
| import JsonEditor from "./jsonEditor.vue"; | import JsonEditor from "./jsonEditor.vue"; | ||||||
| import {DvCompData} from "dui/dv"; | import {DvCompData} from "@dui/dv"; | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   name: "datasourcePicker", |   name: "datasourcePicker", | ||||||
|   | |||||||
| @@ -1,62 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <div class="AppHealthReport"> |  | ||||||
|     <keep-alive :include="['List']"> |  | ||||||
|       <component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component> |  | ||||||
|     </keep-alive> |  | ||||||
|   </div> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   import List from './components/List.vue' |  | ||||||
|   import Detail from './components/Detail.vue' |  | ||||||
|  |  | ||||||
|   export default { |  | ||||||
|     name: 'AppHealthReport', |  | ||||||
|     label: '健康上报', |  | ||||||
|  |  | ||||||
|     components: { |  | ||||||
|       List, |  | ||||||
|       Detail |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object, |  | ||||||
|       permissions: Function |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data () { |  | ||||||
|       return { |  | ||||||
|         component: 'List', |  | ||||||
|         params: {} |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       onChange (data) { |  | ||||||
|         if (data.type === 'Detail') { |  | ||||||
|           this.component = 'Detail' |  | ||||||
|           this.isShowDetail = true |  | ||||||
|           this.params = data.params |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (data.type === 'list') { |  | ||||||
|           this.component = 'List' |  | ||||||
|           this.params = data.params |  | ||||||
|  |  | ||||||
|           this.$nextTick(() => { |  | ||||||
|             if (data.isRefresh) { |  | ||||||
|               this.$refs.component.getList() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
|   .AppHealthReport { |  | ||||||
|     height: 100%; |  | ||||||
|   } |  | ||||||
| </style> |  | ||||||
| @@ -1,316 +0,0 @@ | |||||||
|  <template> |  | ||||||
|   <ai-detail isHasSidebar> |  | ||||||
|     <template slot="title"> |  | ||||||
|       <ai-title title="详情" isShowBack isShowBottomBorder @onBackClick="cancel(true)"> |  | ||||||
|       </ai-title> |  | ||||||
|     </template> |  | ||||||
|     <template slot="content"> |  | ||||||
|       <AiSidebar :tabTitle="tabList" v-model="currIndex"></AiSidebar> |  | ||||||
|       <div v-show="currIndex === 0"> |  | ||||||
|         <ai-card title="基本信息" v-show="currIndex === 0"> |  | ||||||
|           <template #content> |  | ||||||
|             <ai-wrapper |  | ||||||
|               label-width="120px"> |  | ||||||
|               <ai-info-item label="姓名" :value="info.name"></ai-info-item> |  | ||||||
|               <ai-info-item label="上报时间" :value="info.createTime"></ai-info-item> |  | ||||||
|               <ai-info-item label="身份证号" :value="info.idNumber"></ai-info-item> |  | ||||||
|               <ai-info-item label="所属地区" :value="info.areaName"></ai-info-item> |  | ||||||
|               <ai-info-item label="详细地址" isLine :value="info.address"></ai-info-item> |  | ||||||
|             </ai-wrapper> |  | ||||||
|           </template> |  | ||||||
|         </ai-card> |  | ||||||
|       </div> |  | ||||||
|       <ai-card title="每日上报" v-show="currIndex === 1"> |  | ||||||
|         <template #content> |  | ||||||
|           <ai-table |  | ||||||
|             class="detail-table__table" |  | ||||||
|             :tableData="tableData" |  | ||||||
|             :col-configs="colConfigs" |  | ||||||
|             :total="total" |  | ||||||
|             :current.sync="search.current" |  | ||||||
|             :size.sync="search.size" |  | ||||||
|             @getList="getList"> |  | ||||||
|             <el-table-column slot="options" width="140px" fixed="right" label="操作" align="center"> |  | ||||||
|               <template slot-scope="{ row }"> |  | ||||||
|                 <div class="table-options"> |  | ||||||
|                   <el-button type="text" @click="toDetail(row.id)">详情</el-button> |  | ||||||
|                 </div> |  | ||||||
|               </template> |  | ||||||
|             </el-table-column> |  | ||||||
|           </ai-table> |  | ||||||
|           <ai-dialog |  | ||||||
|             :visible.sync="isShow" |  | ||||||
|             width="890px" |  | ||||||
|             customFooter |  | ||||||
|             title="上报详情"> |  | ||||||
|             <ai-bar title="健康状况"></ai-bar> |  | ||||||
|             <ai-wrapper |  | ||||||
|               label-width="120px"> |  | ||||||
|               <ai-info-item label="当前体温"> |  | ||||||
|                 <span :style="{color: reportInfo.temperature > 37.3 ? '#FF4466' : '#42D784'}">{{ reportInfo.temperature }}℃</span> |  | ||||||
|               </ai-info-item> |  | ||||||
|               <ai-info-item label="14天内是否接触新冠确诊或疑似患者"> |  | ||||||
|                 <span :style="{color: reportInfo.touchInFourteen === '0' ? '#42D784' : '#FF4466'}">{{ $dict.getLabel('epidemicTouchInFourteen', reportInfo.touchInFourteen) }}</span> |  | ||||||
|               </ai-info-item> |  | ||||||
|               <ai-info-item label="当前健康状况" isLine> |  | ||||||
|                 <span :style="{color: !reportInfo.isHealth ? '#42D784' : '#FF4466'}">{{ reportInfo.healthName }}</span> |  | ||||||
|               </ai-info-item> |  | ||||||
|             </ai-wrapper> |  | ||||||
|             <ai-bar title="核酸检测信息"></ai-bar> |  | ||||||
|             <ai-wrapper |  | ||||||
|               label-width="120px"> |  | ||||||
|               <ai-info-item label="检测日期"> |  | ||||||
|                 <span>{{ reportInfo.checkTime && reportInfo.checkTime.split(' ')[0] }}</span> |  | ||||||
|               </ai-info-item> |  | ||||||
|               <ai-info-item label="检测结果"> |  | ||||||
|                 <span :style="{color: reportInfo.checkResult === '0' ? '#42D784' : '#FF4466'}">{{ $dict.getLabel('epidemicRecentTestResult', reportInfo.checkResult) }}</span> |  | ||||||
|               </ai-info-item> |  | ||||||
|               <ai-info-item label="健康码状态"> |  | ||||||
|                 <span :style="{color: (reportInfo.healthCode === '0' || reportInfo.healthCode === '1') ? '#42D784' : '#FF4466'}">{{ $dict.getLabel('epidemicHealthCode', reportInfo.healthCode) }}</span> |  | ||||||
|               </ai-info-item> |  | ||||||
|               <ai-info-item label="已接种疫苗次数"> |  | ||||||
|                 <span>{{ $dict.getLabel('epidemicVaccineTime', reportInfo.vaccine) }}</span> |  | ||||||
|               </ai-info-item> |  | ||||||
|               <ai-info-item label="本人健康码截图" isLine> |  | ||||||
|                 <ai-uploader |  | ||||||
|                   :instance="instance" |  | ||||||
|                   v-model="reportInfo.checkPhoto" |  | ||||||
|                   disabled |  | ||||||
|                   :limit="9"> |  | ||||||
|                 </ai-uploader> |  | ||||||
|               </ai-info-item> |  | ||||||
|             </ai-wrapper> |  | ||||||
|             <div class="dialog-footer" slot="footer"> |  | ||||||
|               <el-button @click="isShow = false">关闭</el-button> |  | ||||||
|             </div> |  | ||||||
|           </ai-dialog> |  | ||||||
|         </template> |  | ||||||
|       </ai-card> |  | ||||||
|       <div v-show="currIndex === 2"> |  | ||||||
|         <ai-card title="异常处理"> |  | ||||||
|           <template #right> |  | ||||||
|             <el-button type="primary" v-if="info.status === '0'" @click="release">解除异常</el-button> |  | ||||||
|           </template> |  | ||||||
|           <template #content> |  | ||||||
|             <ai-wrapper |  | ||||||
|               label-width="120px"> |  | ||||||
|               <ai-info-item label="姓名" :value="info.name"></ai-info-item> |  | ||||||
|               <ai-info-item label="填报时间" :value="info.createTime"></ai-info-item> |  | ||||||
|               <ai-info-item label="身份证号" :value="info.idNumber"></ai-info-item> |  | ||||||
|               <ai-info-item label="手机号码" :value="info.phone"></ai-info-item> |  | ||||||
|               <ai-info-item label="异常状况" isLine> |  | ||||||
|                 <span :style="{color: info.unusual ? 'red' : '#333'}">{{ info.unusual || '-' }}</span> |  | ||||||
|               </ai-info-item> |  | ||||||
|               <ai-info-item label="异常解除人" v-if="info.releaseName && info.status === '1'" :value="info.releaseName"></ai-info-item> |  | ||||||
|               <ai-info-item label="异常解除时间" v-if="info.releaseTime && info.status === '1'" :value="info.releaseTime"></ai-info-item> |  | ||||||
|             </ai-wrapper> |  | ||||||
|           </template> |  | ||||||
|         </ai-card> |  | ||||||
|         <ai-card title="异常情况记录"> |  | ||||||
|           <template #right> |  | ||||||
|             <el-button type="primary" v-if="info.status === '0'" @click="isShowAdd = true">添加记录</el-button> |  | ||||||
|           </template> |  | ||||||
|           <template #content> |  | ||||||
|             <ai-table |  | ||||||
|               :tableData="recordList" |  | ||||||
|               :col-configs="recordConfigs" |  | ||||||
|               :total="recordTotal" |  | ||||||
|               :current.sync="recordSerch.current" |  | ||||||
|               :size.sync="recordSerch.size" |  | ||||||
|               @getList="getRecordList"> |  | ||||||
|               <el-table-column slot="options" width="120px" fixed="right" label="操作" align="center"> |  | ||||||
|                 <template slot-scope="{ row }"> |  | ||||||
|                   <div class="table-options"> |  | ||||||
|                     <el-button type="text" @click="remove(row.id)">删除</el-button> |  | ||||||
|                   </div> |  | ||||||
|                 </template> |  | ||||||
|               </el-table-column> |  | ||||||
|             </ai-table> |  | ||||||
|           </template> |  | ||||||
|         </ai-card> |  | ||||||
|         <ai-dialog |  | ||||||
|           :visible.sync="isShowAdd" |  | ||||||
|           width="800px" |  | ||||||
|           @close="form.content = ''" |  | ||||||
|           title="添加异常记录" |  | ||||||
|           @onConfirm="onConfirm"> |  | ||||||
|           <el-form class="ai-form" label-width="120px" :model="form" ref="form"> |  | ||||||
|             <el-form-item label="异常记录" prop="content" style="width: 100%;" :rules="[{ required: true, message: '请输入异常记录' }]"> |  | ||||||
|               <el-input type="textarea" :rows="5" :maxlength="500" v-model="form.content" clearable placeholder="请输入异常记录" show-word-limit></el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|           </el-form> |  | ||||||
|         </ai-dialog> |  | ||||||
|       </div> |  | ||||||
|     </template> |  | ||||||
|   </ai-detail> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   export default { |  | ||||||
|     name: 'Detail', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object, |  | ||||||
|       params: Object |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data () { |  | ||||||
|       return { |  | ||||||
|         total: 0, |  | ||||||
|         info: {}, |  | ||||||
|         id: '', |  | ||||||
|         isShowAdd: false, |  | ||||||
|         recordTotal: 0, |  | ||||||
|         recordSerch: { |  | ||||||
|           current: 1, |  | ||||||
|           size: 10 |  | ||||||
|         }, |  | ||||||
|         search: { |  | ||||||
|           current: 1, |  | ||||||
|           size: 10 |  | ||||||
|         }, |  | ||||||
|         form: { |  | ||||||
|           content: '' |  | ||||||
|         }, |  | ||||||
|         recordConfigs: [ |  | ||||||
|           {prop: 'content', label: '异常记录', align: 'center' }, |  | ||||||
|           {prop: 'createTime', label: '创建时间', align: 'center'}, |  | ||||||
|           {prop: 'createUserName', label: '记录人', align: 'center' } |  | ||||||
|         ], |  | ||||||
|         reportInfo: {}, |  | ||||||
|         isShow: false, |  | ||||||
|         currIndex: 0, |  | ||||||
|         tableData: [], |  | ||||||
|         recordList: [], |  | ||||||
|         colConfigs: [ |  | ||||||
|           {prop: 'createTime', label: '上报日期', align: 'center', dateFormat: 'YYYY-MM-DD'}, |  | ||||||
|           {prop: 'status', label: '健康状态', align: 'center', format: v => v === '0' ? '异常' : '正常' } |  | ||||||
|         ], |  | ||||||
|         tabList: ['基本信息', '每日上报', '异常处理'] |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     created () { |  | ||||||
|       if (this.params && this.params.id) { |  | ||||||
|         this.id = this.params.id |  | ||||||
|         this.dict.load(['epidemicRecentHealth', 'epidemicRecentTravel', 'epidemicTouchInFourteen', 'epidemicMemberType', 'epidemicRecentTestResult']).then(() => { |  | ||||||
|           this.getInfo(this.params.id) |  | ||||||
|           this.getList() |  | ||||||
|           this.getRecordList() |  | ||||||
|         }) |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       getInfo (id) { |  | ||||||
|         this.instance.post(`/app/appepidemicreportmember/queryDetailById?id=${id}`).then(res => { |  | ||||||
|           if (res.code === 0) { |  | ||||||
|             this.info = res.data |  | ||||||
|             this.currIndex = 0 |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       getRecordList () { |  | ||||||
|         this.instance.post(`/app/appepidemicunusuallog/list`, null, { |  | ||||||
|           params: { |  | ||||||
|             ...this.search, |  | ||||||
|             recordId: this.params.id |  | ||||||
|           } |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.recordList = res.data.records |  | ||||||
|             this.recordTotal = res.data.total |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       onConfirm() { |  | ||||||
|         this.$refs.form.validate(v => { |  | ||||||
|           if (v) { |  | ||||||
|             this.instance.post('/app/appepidemicunusuallog/addOrUpdate', { |  | ||||||
|               ...this.form, |  | ||||||
|               recordId: this.params.id |  | ||||||
|             }).then(res => { |  | ||||||
|               if (res?.code == 0) { |  | ||||||
|                 this.isShowAdd = false |  | ||||||
|                 this.getRecordList(this.params.id) |  | ||||||
|                 this.$message.success('添加成功!') |  | ||||||
|               } |  | ||||||
|             }) |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       release () { |  | ||||||
|         this.$confirm('确定解除异常?').then(() => { |  | ||||||
|           this.instance.post(`/app/appepidemicreportmember/release`, { |  | ||||||
|             id: this.params.id |  | ||||||
|           }).then(res => { |  | ||||||
|             if (res.code == 0) { |  | ||||||
|               this.$message.success('解除异常成功!') |  | ||||||
|               this.currIndex = 0 |  | ||||||
|               this.getInfo(this.params.id) |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       remove(id) { |  | ||||||
|         this.$confirm('确定删除该数据?').then(() => { |  | ||||||
|           this.instance.post(`/app/appepidemicunusuallog/delete?ids=${id}`).then(res => { |  | ||||||
|             if (res.code == 0) { |  | ||||||
|               this.$message.success('删除成功!') |  | ||||||
|               this.getRecordList(this.params.id) |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       toDetail (id) { |  | ||||||
|         this.instance.post(`/app/appepidemichealthreport/queryDetailById?id=${id}`).then(res => { |  | ||||||
|           if (res.code === 0) { |  | ||||||
|             this.reportInfo = res.data |  | ||||||
|             this.reportInfo.checkPhoto = JSON.parse(res.data.checkPhoto) |  | ||||||
|             let healthName = '' |  | ||||||
|             this.reportInfo.isHealth = false |  | ||||||
|             res.data.health.split(',').forEach(v => { |  | ||||||
|               if (v > 0) { |  | ||||||
|                 this.reportInfo.isHealth = true |  | ||||||
|               } |  | ||||||
|               healthName = healthName + this.dict.getLabel('epidemicRecentHealth', v) |  | ||||||
|             }) |  | ||||||
|             this.reportInfo.healthName = healthName |  | ||||||
|  |  | ||||||
|             this.isShow = true |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       getList () { |  | ||||||
|         this.instance.post(`/app/appepidemichealthreport/list`, null, { |  | ||||||
|           params: { |  | ||||||
|             ...this.search, |  | ||||||
|             memberId: this.params.id |  | ||||||
|           } |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.tableData = res.data.records |  | ||||||
|             this.total = res.data.total |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       cancel (isRefresh) { |  | ||||||
|         this.$emit('change', { |  | ||||||
|           type: 'list', |  | ||||||
|           isRefresh: !!isRefresh |  | ||||||
|         }) |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| </style> |  | ||||||
| @@ -1,293 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <ai-list class="list"> |  | ||||||
|     <ai-title slot="title" title="健康上报" v-if="search.areaId" isShowBottomBorder :instance="instance" :disabledLevel="disabledLevel" isShowArea v-model="search.areaId" @change="changeArea"></ai-title> |  | ||||||
|     <template slot="content"> |  | ||||||
|       <div class="statistics-top"> |  | ||||||
|         <div class="statistics-top__item"> |  | ||||||
|           <span>上报人数</span> |  | ||||||
|           <h2 style="color: #2266FF;">{{ info.total }}</h2> |  | ||||||
|         </div> |  | ||||||
|         <div class="statistics-top__item"> |  | ||||||
|           <span>今日上报</span> |  | ||||||
|           <h2 style="color: #22AA99;">{{ info.today }}</h2> |  | ||||||
|         </div> |  | ||||||
|         <div class="statistics-top__item"> |  | ||||||
|           <span>今日未报</span> |  | ||||||
|           <h2 style="color: #F8B425">{{ info.unReport }}</h2> |  | ||||||
|         </div> |  | ||||||
|         <div class="statistics-top__item"> |  | ||||||
|           <span>今日异常</span> |  | ||||||
|           <h2 style="color: red">{{ info.unusual }}</h2> |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|       <div class="content"> |  | ||||||
|         <ai-search-bar bottomBorder> |  | ||||||
|           <template #left> |  | ||||||
|             <ai-select |  | ||||||
|               v-model="search.checkResult" |  | ||||||
|               clearable |  | ||||||
|               placeholder="请选择检查结果" |  | ||||||
|               :selectList="dict.getDict('epidemicRecentTestResult')" |  | ||||||
|               @change="search.current = 1, getList()"> |  | ||||||
|             </ai-select> |  | ||||||
|             <ai-select |  | ||||||
|               v-model="search.today" |  | ||||||
|               clearable |  | ||||||
|               placeholder="今日是否上报" |  | ||||||
|               :selectList="dictList" |  | ||||||
|               @change="search.current = 1, getList()"> |  | ||||||
|             </ai-select> |  | ||||||
|             <ai-download :instance="instance" url="/app/appepidemicreportmember/export" :params="search" fileName="健康上报" :disabled="tableData.length == 0"> |  | ||||||
|               <el-button icon="iconfont iconExported" :disabled="tableData.length == 0">导出</el-button> |  | ||||||
|             </ai-download> |  | ||||||
|           </template> |  | ||||||
|           <template #right> |  | ||||||
|             <el-input |  | ||||||
|               v-model="search.name" |  | ||||||
|               size="small" |  | ||||||
|               placeholder="请输入姓名" |  | ||||||
|               clearable |  | ||||||
|               v-throttle="() => {search.current = 1, getList()}" |  | ||||||
|               @clear="search.current = 1, search.name = '', getList()" |  | ||||||
|               suffix-icon="iconfont iconSearch"> |  | ||||||
|             </el-input> |  | ||||||
|           </template> |  | ||||||
|         </ai-search-bar> |  | ||||||
|         <ai-table |  | ||||||
|           :tableData="tableData" |  | ||||||
|           :col-configs="colConfigs" |  | ||||||
|           :total="total" |  | ||||||
|           v-loading="loading" |  | ||||||
|           style="margin-top: 16px;" |  | ||||||
|           :current.sync="search.current" |  | ||||||
|           :size.sync="search.size" |  | ||||||
|           @getList="getList"> |  | ||||||
|           <el-table-column slot="healthCode" align="center" label="健康码"> |  | ||||||
|             <template slot-scope="{ row }"> |  | ||||||
|               <ai-uploader |  | ||||||
|                 v-if="row.healthCode" |  | ||||||
|                 :instance="instance" |  | ||||||
|                 :value="JSON.parse(row.healthCode)" |  | ||||||
|                 disabled |  | ||||||
|                 :limit="1"> |  | ||||||
|               </ai-uploader> |  | ||||||
|             </template> |  | ||||||
|           </el-table-column> |  | ||||||
|           <el-table-column slot="options" width="140px" fixed="right" label="操作" align="center"> |  | ||||||
|             <template slot-scope="{ row }"> |  | ||||||
|               <div class="table-options"> |  | ||||||
|                 <el-button type="text" @click="toDetail(row.id)">详情</el-button> |  | ||||||
|                 <el-button type="text" @click="remove(row.id)">删除</el-button> |  | ||||||
|               </div> |  | ||||||
|             </template> |  | ||||||
|           </el-table-column> |  | ||||||
|         </ai-table> |  | ||||||
|       </div> |  | ||||||
|     </template> |  | ||||||
|   </ai-list> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   import { mapState } from 'vuex' |  | ||||||
|   export default { |  | ||||||
|     name: 'List', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data () { |  | ||||||
|       return { |  | ||||||
|         search: { |  | ||||||
|           current: 1, |  | ||||||
|           size: 10, |  | ||||||
|           name: '', |  | ||||||
|           checkResult: '', |  | ||||||
|           areaId: '', |  | ||||||
|           today: '' |  | ||||||
|         }, |  | ||||||
|         dictList: [{ |  | ||||||
|           dictName: '否', |  | ||||||
|           dictValue: '0' |  | ||||||
|         }, { |  | ||||||
|           dictName: '是', |  | ||||||
|           dictValue: '1' |  | ||||||
|         }], |  | ||||||
|         info: {}, |  | ||||||
|         colConfigs: [ |  | ||||||
|           { prop: 'name', label: '姓名' }, |  | ||||||
|           { prop: 'phone', align: 'center', label: '手机号码' }, |  | ||||||
|           { prop: 'areaName', align: 'center', label: '所属地区', width: '200px' }, |  | ||||||
|           { prop: 'reportTime', align: 'center', label: '上报时间', width: '200px' }, |  | ||||||
|           { |  | ||||||
|             prop: 'vaccine', |  | ||||||
|             align: 'center', |  | ||||||
|             label: '已接种情况', |  | ||||||
|             render: (h, {row}) => { |  | ||||||
|               return h('span', { |  | ||||||
|                 style: { |  | ||||||
|                 } |  | ||||||
|               }, row.today === '0' ? '-' : (row.vaccine || 0 + '次')) |  | ||||||
|             } |  | ||||||
|           }, |  | ||||||
|           { prop: 'healthCode', align: 'center', label: '健康码', format: v => v ? this.dict.getLabel('epidemicHealthCode', v) : '-' }, |  | ||||||
|           { prop: 'checkTime', align: 'center', label: '核酸日期', format: v => v ? v.split(' ')[0] : '-' }, |  | ||||||
|           { prop: 'checkResult', align: 'center', label: '检测结果', format: v => v ? this.dict.getLabel('epidemicRecentTestResult', v) : '-' }, |  | ||||||
|           { |  | ||||||
|             prop: 'status', |  | ||||||
|             align: 'center', |  | ||||||
|             label: '健康状态', |  | ||||||
|             render: (h, {row}) => { |  | ||||||
|               return h('span', { |  | ||||||
|                 style: { |  | ||||||
|                   color: row.status === '0' ? 'red' : '#333' |  | ||||||
|                 } |  | ||||||
|               }, row.today === '0' ? '-' : (row.status === '0' ? '异常' : '正常')) |  | ||||||
|             } |  | ||||||
|           }, |  | ||||||
|           { prop: 'today', align: 'center', label: '今日上报', format: v => v === '0' ? '未上报' : '已上报' }, |  | ||||||
|         ], |  | ||||||
|         tableData: [], |  | ||||||
|         total: 0, |  | ||||||
|         loading: false, |  | ||||||
|         disabledLevel: 0 |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     computed: { |  | ||||||
|       ...mapState(['user']), |  | ||||||
|  |  | ||||||
|       param () { |  | ||||||
|         return { |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     created () { |  | ||||||
|       this.disabledLevel = this.user.info.areaList.length - 1 |  | ||||||
|       this.search.areaId = this.user.info.areaId |  | ||||||
|       this.loading = true |  | ||||||
|       this.dict.load(['epidemicTouchInFourteen', 'epidemicRecentHealth', 'epidemicRecentTestResult', 'epidemicHealthCode', 'epidemicVaccineTime']).then(() => { |  | ||||||
|         this.getList() |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       getList () { |  | ||||||
|         this.instance.post(`/app/appepidemicreportmember/list`, null, { |  | ||||||
|           params: { |  | ||||||
|             ...this.search |  | ||||||
|           } |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.tableData = res.data.records |  | ||||||
|             this.total = res.data.total |  | ||||||
|             this.loading = false |  | ||||||
|           } else { |  | ||||||
|             this.loading = false |  | ||||||
|           } |  | ||||||
|         }).catch(() => { |  | ||||||
|           this.loading = false |  | ||||||
|         }) |  | ||||||
|  |  | ||||||
|         this.getTotalInfo() |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       remove(id) { |  | ||||||
|         this.$confirm('确定删除该数据?').then(() => { |  | ||||||
|           this.instance.post(`/app/appepidemicreportmember/delete?ids=${id}`).then(res => { |  | ||||||
|             if (res.code == 0) { |  | ||||||
|               this.$message.success('删除成功!') |  | ||||||
|               this.getTotalInfo() |  | ||||||
|               this.getList() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       toDetail (id) { |  | ||||||
|         this.$emit('change', { |  | ||||||
|           type: 'Detail', |  | ||||||
|           params: { |  | ||||||
|             id: id || '' |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       changeArea () { |  | ||||||
|         this.search.current = 1 |  | ||||||
|  |  | ||||||
|         this.$nextTick(() => { |  | ||||||
|           this.getList() |  | ||||||
|           this.getTotalInfo() |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       getTotalInfo () { |  | ||||||
|         this.instance.post(`/app/appepidemicreportmember/statistic`, null, { |  | ||||||
|           params: { |  | ||||||
|             areaId: this.search.areaId |  | ||||||
|           } |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.info = res.data |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
|   .list { |  | ||||||
|     :deep( .ai-list__content ){ |  | ||||||
|       padding: 0!important; |  | ||||||
|  |  | ||||||
|       .ai-list__content--right-wrapper { |  | ||||||
|         background: transparent!important; |  | ||||||
|         box-shadow: none!important; |  | ||||||
|         margin: 0!important; |  | ||||||
|         padding: 12px 16px 12px!important; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     .statistics-top { |  | ||||||
|       display: flex; |  | ||||||
|       align-items: center; |  | ||||||
|       margin-bottom: 20px; |  | ||||||
|  |  | ||||||
|       & > div { |  | ||||||
|         flex: 1; |  | ||||||
|         height: 96px; |  | ||||||
|         line-height: 1; |  | ||||||
|         margin-right: 20px; |  | ||||||
|         padding: 16px 24px; |  | ||||||
|         background: #FFFFFF; |  | ||||||
|         box-shadow: 0px 4px 6px -2px rgba(15, 15, 21, 0.15); |  | ||||||
|         border-radius: 4px; |  | ||||||
|  |  | ||||||
|         &:last-child { |  | ||||||
|           margin-right: 0; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         h3 { |  | ||||||
|           font-size: 24px; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         span { |  | ||||||
|           display: block; |  | ||||||
|           margin-bottom: 16px; |  | ||||||
|           color: #888888; |  | ||||||
|           font-size: 16px; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .content { |  | ||||||
|       padding: 16px; |  | ||||||
|       background: #FFFFFF; |  | ||||||
|       box-shadow: 0px 4px 6px -2px rgba(15, 15, 21, 0.15); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </style> |  | ||||||
| @@ -1,105 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <ai-list class="AppReturnHomeRegister" v-if="!isShowDetail"> |  | ||||||
|     <template slot="title"> |  | ||||||
|       <ai-title title="返乡登记" :isShowBottomBorder="false" :fullname.sync="areaName" v-model="areaId" :instance="instance" @change="onAreaChange"></ai-title> |  | ||||||
|     </template> |  | ||||||
|     <template slot="tabs"> |  | ||||||
|       <el-tabs v-model="currIndex"> |  | ||||||
|         <el-tab-pane v-for="(tab,i) in tabs" :key="i" :label="tab.label"> |  | ||||||
|           <component :areaId="areaId" :ref="String(i)" v-if="currIndex == i" :is="tab.comp" @change="onChange" lazy :instance="instance" :dict="dict" :permissions="permissions"/> |  | ||||||
|         </el-tab-pane> |  | ||||||
|       </el-tabs> |  | ||||||
|     </template> |  | ||||||
|   </ai-list> |  | ||||||
|   <Detail v-else-if="component === 'Detail'" :params="params" :instance="instance" :dict="dict" :permissions="permissions" @change="onChange"></Detail> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   import List from './components/List.vue' |  | ||||||
|   import Detail from './components/Detail.vue' |  | ||||||
|   import AbnormalList from './components/AbnormalList.vue' |  | ||||||
|   import { mapState } from 'vuex' |  | ||||||
|  |  | ||||||
|   export default { |  | ||||||
|     name: 'AppReturnHomeRegister', |  | ||||||
|     label: '返乡登记', |  | ||||||
|  |  | ||||||
|     components: { |  | ||||||
|       List, |  | ||||||
|       Detail, |  | ||||||
|       AbnormalList |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object, |  | ||||||
|       permissions: Function |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     computed: { |  | ||||||
|       ...mapState(['user']), |  | ||||||
|  |  | ||||||
|       tabs () { |  | ||||||
|         const tabList = [ |  | ||||||
|           {label: '返乡登记', name: 'List', comp: List, permission: ''}, |  | ||||||
|           // {label: '历史异常人员', name: 'AbnormalList', comp: AbnormalList, permission: ''} |  | ||||||
|         ] |  | ||||||
|  |  | ||||||
|         return tabList |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data () { |  | ||||||
|       return { |  | ||||||
|         activeName: 'JoinEvent', |  | ||||||
|         currIndex: '0', |  | ||||||
|         component: 'List', |  | ||||||
|         params: {}, |  | ||||||
|         areaId: '', |  | ||||||
|         isShowDetail: false, |  | ||||||
|         areaName: '' |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     created () { |  | ||||||
|       this.areaId = this.user.info.areaId |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       onChange (data) { |  | ||||||
|         if (data.type === 'Detail') { |  | ||||||
|           this.component = 'Detail' |  | ||||||
|           this.isShowDetail = true |  | ||||||
|           this.params = data.params |  | ||||||
|         } |  | ||||||
|         if (data.type === 'AbnormalList') { |  | ||||||
|           this.component = 'AbnormalList' |  | ||||||
|           this.isShowDetail = false |  | ||||||
|           this.params = data.params |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (data.type === 'List') { |  | ||||||
|           this.component = 'List' |  | ||||||
|           this.isShowDetail = false |  | ||||||
|           this.params = data.params |  | ||||||
|  |  | ||||||
|           this.$nextTick(() => { |  | ||||||
|             if (data.isRefresh) { |  | ||||||
|               this.$refs.component.getList() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         } |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       onAreaChange () { |  | ||||||
|         this.$refs[this.currIndex][0].changeArea() |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
|   .AppReturnHomeRegister { |  | ||||||
|     height: 100%; |  | ||||||
|   } |  | ||||||
| </style> |  | ||||||
| @@ -1,200 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <ai-list isTabs> |  | ||||||
|     <template slot="content"> |  | ||||||
|       <ai-search-bar bottomBorder> |  | ||||||
|         <template #left> |  | ||||||
|           <ai-select |  | ||||||
|             v-model="search.status" |  | ||||||
|             clearable |  | ||||||
|             placeholder="请选择健康状态" |  | ||||||
|             :selectList="dictList" |  | ||||||
|             @change="search.current = 1, getList()"> |  | ||||||
|           </ai-select> |  | ||||||
|           <ai-download :instance="instance" url="/app/appepidemicbackhomerecord/export" :params="param" fileName="返乡登记" :disabled="tableData.length == 0"> |  | ||||||
|             <el-button icon="iconfont iconExported" :disabled="tableData.length == 0">导出</el-button> |  | ||||||
|           </ai-download> |  | ||||||
|         </template> |  | ||||||
|         <template #right> |  | ||||||
|           <el-input |  | ||||||
|             v-model="search.name" |  | ||||||
|             size="small" |  | ||||||
|             placeholder="请输入姓名" |  | ||||||
|             clearable |  | ||||||
|             v-throttle="() => {search.current = 1, getList()}" |  | ||||||
|             @clear="search.current = 1, search.name = '', getList()" |  | ||||||
|             suffix-icon="iconfont iconSearch"> |  | ||||||
|           </el-input> |  | ||||||
|         </template> |  | ||||||
|       </ai-search-bar> |  | ||||||
|       <ai-table |  | ||||||
|         :tableData="tableData" |  | ||||||
|         :col-configs="colConfigs" |  | ||||||
|         :total="total" |  | ||||||
|         v-loading="loading" |  | ||||||
|         style="margin-top: 16px;" |  | ||||||
|         :current.sync="search.current" |  | ||||||
|         :size.sync="search.size" |  | ||||||
|         @getList="getList"> |  | ||||||
|         <el-table-column slot="options" width="140px" fixed="right" label="操作" align="center"> |  | ||||||
|           <template slot-scope="{ row }"> |  | ||||||
|             <div class="table-options"> |  | ||||||
|               <el-button type="text" @click="toDetail(row.id)">详情</el-button> |  | ||||||
|               <el-button type="text" @click="remove(row.id)">删除</el-button> |  | ||||||
|             </div> |  | ||||||
|           </template> |  | ||||||
|         </el-table-column> |  | ||||||
|       </ai-table> |  | ||||||
|     </template> |  | ||||||
|   </ai-list> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   import { mapState } from 'vuex' |  | ||||||
|   export default { |  | ||||||
|     name: 'AbnormalList', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data () { |  | ||||||
|       return { |  | ||||||
|         search: { |  | ||||||
|           current: 1, |  | ||||||
|           size: 10, |  | ||||||
|           name: '', |  | ||||||
|           arriveAreaId: '', |  | ||||||
|           status: '' |  | ||||||
|         }, |  | ||||||
|         dictList: [{ |  | ||||||
|           dictName: '异常', |  | ||||||
|           dictValue: '0' |  | ||||||
|         }, { |  | ||||||
|           dictName: '正常', |  | ||||||
|           dictValue: '1' |  | ||||||
|         }], |  | ||||||
|         info: {}, |  | ||||||
|         colConfigs: [ |  | ||||||
|           { prop: 'name', label: '姓名' }, |  | ||||||
|           { prop: 'phone', align: 'center', label: '手机号码' }, |  | ||||||
|           { prop: 'startTime', align: 'center', label: '出发时间', format: v => v.substr(0, v.length - 3) }, |  | ||||||
|           { |  | ||||||
|             prop: 'startAreaName', |  | ||||||
|             align: 'center', |  | ||||||
|             label: '出发地区' |  | ||||||
|           }, |  | ||||||
|           { prop: 'arriveTime', align: 'center', label: '到达时间', format: v => v.substr(0, v.length - 3) }, |  | ||||||
|           { |  | ||||||
|             prop: 'arriveAreaName', |  | ||||||
|             align: 'center', |  | ||||||
|             label: '到达地区' |  | ||||||
|           }, |  | ||||||
|           { prop: 'checkTime', align: 'center', label: '核酸日期', format: v => v.split(' ')[0] }, |  | ||||||
|           { |  | ||||||
|             prop: 'status', |  | ||||||
|             align: 'center', |  | ||||||
|             label: '健康状态', |  | ||||||
|             render: (h, {row}) => { |  | ||||||
|               return h('span', { |  | ||||||
|                 style: { |  | ||||||
|                   color: row.status === '0' ? 'red' : '#333' |  | ||||||
|                 } |  | ||||||
|               }, row.status === '0' ? '异常' : '正常') |  | ||||||
|             } |  | ||||||
|           } |  | ||||||
|         ], |  | ||||||
|         ids: [], |  | ||||||
|         tableData: [], |  | ||||||
|         total: 0, |  | ||||||
|         loading: false, |  | ||||||
|         disabledLevel: 0 |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     computed: { |  | ||||||
|       ...mapState(['user']), |  | ||||||
|  |  | ||||||
|       param () { |  | ||||||
|         return this.search |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     created () { |  | ||||||
|       this.disabledLevel = this.user.info.areaList.length - 1 |  | ||||||
|       this.search.arriveAreaId = this.user.info.areaId |  | ||||||
|       this.loading = true |  | ||||||
|       this.dict.load(['marriageType', 'marriagePersonType', 'modeType']).then(() => { |  | ||||||
|         this.getList() |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       getList () { |  | ||||||
|         this.instance.post(`/app/appepidemicbackhomerecord/list`, null, { |  | ||||||
|           params: { |  | ||||||
|             ...this.search |  | ||||||
|           } |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.tableData = res.data.records |  | ||||||
|             this.total = res.data.total |  | ||||||
|             this.loading = false |  | ||||||
|           } else { |  | ||||||
|             this.loading = false |  | ||||||
|           } |  | ||||||
|         }).catch(() => { |  | ||||||
|           this.loading = false |  | ||||||
|         }) |  | ||||||
|  |  | ||||||
|         this.getTotalInfo() |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       toDetail (id) { |  | ||||||
|         this.$emit('change', { |  | ||||||
|           type: 'Detail', |  | ||||||
|           params: { |  | ||||||
|             id: id || '' |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       changeArea () { |  | ||||||
|         this.search.current = 1 |  | ||||||
|  |  | ||||||
|         this.$nextTick(() => { |  | ||||||
|           this.getList() |  | ||||||
|           this.getTotalInfo() |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       remove(id) { |  | ||||||
|         this.$confirm('确定删除该数据?').then(() => { |  | ||||||
|           this.instance.post(`/app/appepidemicbackhomerecord/delete?ids=${id}`).then(res => { |  | ||||||
|             if (res.code == 0) { |  | ||||||
|               this.$message.success('删除成功!') |  | ||||||
|               this.getTotalInfo() |  | ||||||
|               this.getList() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|  |  | ||||||
|       getTotalInfo () { |  | ||||||
|         this.instance.post(`/app/appepidemicbackhomerecord/statistic`, null, { |  | ||||||
|           params: { |  | ||||||
|             areaId: this.search.arriveAreaId |  | ||||||
|           } |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.info = res.data |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| </style> |  | ||||||
| @@ -1,279 +0,0 @@ | |||||||
|  <template> |  | ||||||
|   <ai-detail isHasSidebar> |  | ||||||
|     <template slot="title"> |  | ||||||
|       <ai-title title="返乡登记详情" isShowBack isShowBottomBorder @onBackClick="cancel(false)"> |  | ||||||
|       </ai-title> |  | ||||||
|     </template> |  | ||||||
|     <template slot="content"> |  | ||||||
|       <AiSidebar :tabTitle="tabList" v-model="currIndex"></AiSidebar> |  | ||||||
|       <div v-show="currIndex === 0"> |  | ||||||
|         <ai-card title="基本信息" v-show="currIndex === 0"> |  | ||||||
|           <template #content> |  | ||||||
|             <ai-wrapper |  | ||||||
|               label-width="120px"> |  | ||||||
|               <ai-info-item label="姓名" :value="info.name"></ai-info-item> |  | ||||||
|               <ai-info-item label="填报时间" :value="info.createTime"></ai-info-item> |  | ||||||
|               <ai-info-item label="身份证号" :value="info.idNumber"></ai-info-item> |  | ||||||
|               <ai-info-item label="手机号码" :value="info.phone"></ai-info-item> |  | ||||||
|               <ai-info-item label="人员类别" isLine> |  | ||||||
|                 <span :style="(info.type == 0 || info.type == 3 || info.type ==6 || info.type == 9)? 'color:#42D784;' : 'color:#f46;'">{{dict.getLabel('epidemicRecentPersonType', info.type)}}</span> |  | ||||||
|               </ai-info-item> |  | ||||||
|             </ai-wrapper> |  | ||||||
|           </template> |  | ||||||
|         </ai-card> |  | ||||||
|         <ai-card title="行程信息"> |  | ||||||
|           <template #content> |  | ||||||
|             <ai-wrapper |  | ||||||
|               label-width="120px"> |  | ||||||
|               <ai-info-item label="出发时间" :value="info.startTime"></ai-info-item> |  | ||||||
|               <ai-info-item label="出发地区" > |  | ||||||
|                 <span  :style="{color: info.denger == 1 ? '#FF4466' : '#333'}">{{info.startAreaName}} </span> |  | ||||||
|               </ai-info-item> |  | ||||||
|               <ai-info-item label="出发地址" isLine :value="info.startAddress"></ai-info-item> |  | ||||||
|               <ai-info-item label="出行方式" :value="dict.getLabel('epidemicRecentTravel', info.travelType)"></ai-info-item> |  | ||||||
|               <ai-info-item label="行程描述" isLine :value="info.description"></ai-info-item> |  | ||||||
|               <ai-info-item label="到达时间" :value="info.arriveTime"></ai-info-item> |  | ||||||
|               <ai-info-item label="到达地区" :value="info.arriveAreaName"></ai-info-item> |  | ||||||
|               <ai-info-item label="返乡地址" isLine :value="info.arriveAddress"></ai-info-item> |  | ||||||
|             </ai-wrapper> |  | ||||||
|           </template> |  | ||||||
|         </ai-card> |  | ||||||
|         <ai-card title="健康状况"> |  | ||||||
|           <template #content> |  | ||||||
|             <ai-wrapper |  | ||||||
|               label-width="120px"> |  | ||||||
|               <ai-info-item label="当前体温"> |  | ||||||
|                 <span :style="info.temperature >= 37.3 ? 'color:#f46;' : ''">{{ info.temperature + '℃' }}</span> |  | ||||||
|               </ai-info-item> |  | ||||||
|               <ai-info-item label="14天内是否接触新冠确诊或疑似患者"> |  | ||||||
|                 <span :class="'color-'+info.touchInFourteen">{{$dict.getLabel('epidemicTouchInFourteen', info.touchInFourteen)}}</span>  |  | ||||||
|               </ai-info-item> |  | ||||||
|               <ai-info-item label="当前健康状况">  |  | ||||||
|                 <span></span> |  | ||||||
|                 <span v-for="(item, index) in info.health" :key="index" :style="item != 0 ? 'color:#FF4466;' : ''"><span v-if="index>0">;</span>{{$dict.getLabel('epidemicRecentHealth', item)}}</span> |  | ||||||
|               </ai-info-item> |  | ||||||
|             </ai-wrapper> |  | ||||||
|           </template> |  | ||||||
|         </ai-card> |  | ||||||
|         <ai-card title="核酸检测"> |  | ||||||
|           <template #content> |  | ||||||
|             <ai-wrapper |  | ||||||
|               label-width="120px"> |  | ||||||
|               <ai-info-item label="检测日期" :value="info.checkTime && info.checkTime.split(' ')[0]"></ai-info-item> |  | ||||||
|               <ai-info-item label="检测结果"> |  | ||||||
|                 <span :style="info.checkResult == 1 ? 'color:#f46;' : 'color:#42D784;'">{{$dict.getLabel('epidemicRecentTestResult', info.checkResult)}}</span> |  | ||||||
|               </ai-info-item> |  | ||||||
|               <ai-info-item label="本人健康码截图" isLine> |  | ||||||
|                 <ai-uploader |  | ||||||
|                   :instance="instance" |  | ||||||
|                   v-model="info.checkPhoto" |  | ||||||
|                   disabled |  | ||||||
|                   :limit="9"> |  | ||||||
|                 </ai-uploader> |  | ||||||
|               </ai-info-item> |  | ||||||
|             </ai-wrapper> |  | ||||||
|           </template> |  | ||||||
|         </ai-card> |  | ||||||
|       </div> |  | ||||||
|       <div v-show="currIndex === 1"> |  | ||||||
|         <ai-card title="异常处理"> |  | ||||||
|           <template #right> |  | ||||||
|             <el-button type="primary" v-if="info.status === '0'" @click="release">解除异常</el-button> |  | ||||||
|           </template> |  | ||||||
|           <template #content> |  | ||||||
|             <ai-wrapper |  | ||||||
|               label-width="120px"> |  | ||||||
|               <ai-info-item label="姓名" :value="info.name"></ai-info-item> |  | ||||||
|               <ai-info-item label="填报时间" :value="info.createTime"></ai-info-item> |  | ||||||
|               <ai-info-item label="身份证号" :value="info.idNumber"></ai-info-item> |  | ||||||
|               <ai-info-item label="手机号码" :value="info.phone"></ai-info-item> |  | ||||||
|               <ai-info-item label="人员类别" isLine :value="dict.getLabel('epidemicRecentPersonType', info.type)"></ai-info-item> |  | ||||||
|               <ai-info-item label="异常状况" isLine> |  | ||||||
|                 <span :style="{color: info.unusual ? 'red' : '#333'}">{{ info.unusual || '-' }}</span> |  | ||||||
|               </ai-info-item> |  | ||||||
|               <ai-info-item label="异常解除人" v-if="info.releaseName && info.status === '1'" :value="info.releaseName"></ai-info-item> |  | ||||||
|               <ai-info-item label="异常解除时间" v-if="info.releaseTime && info.status === '1'" :value="info.releaseTime"></ai-info-item> |  | ||||||
|             </ai-wrapper> |  | ||||||
|           </template> |  | ||||||
|         </ai-card> |  | ||||||
|         <ai-card title="异常情况记录"> |  | ||||||
|           <template #right> |  | ||||||
|             <el-button type="primary" v-if="info.status === '0'" @click="isShow = true">添加记录</el-button> |  | ||||||
|           </template> |  | ||||||
|           <template #content> |  | ||||||
|             <ai-table |  | ||||||
|               :tableData="tableData" |  | ||||||
|               :col-configs="colConfigs" |  | ||||||
|               :total="total" |  | ||||||
|               :current.sync="search.current" |  | ||||||
|               :size.sync="search.size" |  | ||||||
|               @getList="getList"> |  | ||||||
|               <el-table-column slot="options" width="120px" fixed="right" label="操作" align="center"> |  | ||||||
|                 <template slot-scope="{ row }"> |  | ||||||
|                   <div class="table-options"> |  | ||||||
|                     <el-button type="text" @click="remove(row.id)">删除</el-button> |  | ||||||
|                   </div> |  | ||||||
|                 </template> |  | ||||||
|               </el-table-column> |  | ||||||
|             </ai-table> |  | ||||||
|           </template> |  | ||||||
|         </ai-card> |  | ||||||
|         <ai-dialog |  | ||||||
|           :visible.sync="isShow" |  | ||||||
|           width="800px" |  | ||||||
|           @close="form.content = ''" |  | ||||||
|           title="添加异常记录" |  | ||||||
|           @onConfirm="onConfirm"> |  | ||||||
|           <el-form class="ai-form" label-width="120px" :model="form" ref="form"> |  | ||||||
|             <el-form-item label="异常记录" prop="content" style="width: 100%;" :rules="[{ required: true, message: '请输入异常记录' }]"> |  | ||||||
|               <el-input type="textarea" :rows="5" :maxlength="500" v-model="form.content" clearable placeholder="请输入异常记录" show-word-limit></el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|           </el-form> |  | ||||||
|         </ai-dialog> |  | ||||||
|       </div> |  | ||||||
|     </template> |  | ||||||
|   </ai-detail> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   export default { |  | ||||||
|     name: 'Detail', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object, |  | ||||||
|       params: Object |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data () { |  | ||||||
|       return { |  | ||||||
|         total: 0, |  | ||||||
|         info: {}, |  | ||||||
|         id: '', |  | ||||||
|         search: { |  | ||||||
|           current: 1, |  | ||||||
|           size: 10 |  | ||||||
|         }, |  | ||||||
|         form: { |  | ||||||
|           content: '' |  | ||||||
|         }, |  | ||||||
|         isShow: false, |  | ||||||
|         currIndex: 0, |  | ||||||
|         tableData: [], |  | ||||||
|         colConfigs: [ |  | ||||||
|           {prop: 'content', label: '异常记录', align: 'center' }, |  | ||||||
|           {prop: 'createTime', label: '创建时间', align: 'center'}, |  | ||||||
|           {prop: 'createUserName', label: '记录人', align: 'center' } |  | ||||||
|         ], |  | ||||||
|         tabList: ['基本信息', '异常处理'] |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     created () { |  | ||||||
|       if (this.params && this.params.id) { |  | ||||||
|         this.id = this.params.id |  | ||||||
|         this.$dict.load(['epidemicRecentHealth', 'epidemicRecentTravel', 'epidemicTouchInFourteen', 'epidemicRecentPersonType', 'epidemicRecentTestResult']).then(() => { |  | ||||||
|           this.getInfo(this.params.id) |  | ||||||
|         }) |  | ||||||
|  |  | ||||||
|         this.getList() |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       getInfo (id) { |  | ||||||
|         this.instance.post(`/app/appepidemicbackhomerecord/queryDetailById?id=${id}`).then(res => { |  | ||||||
|           if (res.code === 0) { |  | ||||||
|             this.info = res.data |  | ||||||
|             this.info.checkPhoto = res.data.checkPhoto ? JSON.parse(res.data.checkPhoto) : [] |  | ||||||
|             let healthName = '' |  | ||||||
|             this.info.isHealth = false |  | ||||||
|             res.data.health.split(',').forEach(v => { |  | ||||||
|               if (v > 0) { |  | ||||||
|                 this.info.isHealth = true |  | ||||||
|               } |  | ||||||
|               healthName = healthName + this.$dict.getLabel('epidemicRecentHealth', v) |  | ||||||
|             }) |  | ||||||
|             this.info.healthName = healthName |  | ||||||
|             this.info.health = this.info.health.split(',') |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       release () { |  | ||||||
|         this.$confirm('确定解除异常?').then(() => { |  | ||||||
|           this.instance.post(`/app/appepidemicbackhomerecord/release?recordId=${this.params.id}`, { |  | ||||||
|             id: this.params.id |  | ||||||
|           }).then(res => { |  | ||||||
|             if (res.code == 0) { |  | ||||||
|               this.$message.success('解除异常成功!') |  | ||||||
|               this.currIndex = 0 |  | ||||||
|               this.getInfo(this.params.id) |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       remove(id) { |  | ||||||
|         this.$confirm('确定删除该数据?').then(() => { |  | ||||||
|           this.instance.post(`/app/appepidemicunusuallog/delete?ids=${id}`).then(res => { |  | ||||||
|             if (res.code == 0) { |  | ||||||
|               this.$message.success('删除成功!') |  | ||||||
|               this.getList() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       onConfirm() { |  | ||||||
|         this.$refs.form.validate(v => { |  | ||||||
|           if (v) { |  | ||||||
|             this.instance.post('/app/appepidemicunusuallog/addOrUpdate', { |  | ||||||
|               ...this.form, |  | ||||||
|               recordId: this.params.id |  | ||||||
|             }).then(res => { |  | ||||||
|               if (res?.code == 0) { |  | ||||||
|                 this.isShow = false |  | ||||||
|                 this.getList() |  | ||||||
|                 this.$message.success('添加成功!') |  | ||||||
|               } |  | ||||||
|             }) |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       getList () { |  | ||||||
|         this.instance.post(`/app/appepidemicunusuallog/list`, null, { |  | ||||||
|           params: { |  | ||||||
|             ...this.search, |  | ||||||
|             recordId: this.params.id |  | ||||||
|           } |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.tableData = res.data.records |  | ||||||
|             this.total = res.data.total |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       cancel () { |  | ||||||
|         this.$emit('change', { |  | ||||||
|           type: 'List', |  | ||||||
|           isRefresh: true |  | ||||||
|         }) |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
|   .color-0{ |  | ||||||
|     color: #42D784; |  | ||||||
|   } |  | ||||||
|   .color-1{ |  | ||||||
|     color: #f46; |  | ||||||
|   } |  | ||||||
|   .color-2{ |  | ||||||
|     color: #1365DD; |  | ||||||
|   } |  | ||||||
| </style> |  | ||||||
| @@ -1,273 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <ai-list class="list" isTabs> |  | ||||||
|     <template slot="content"> |  | ||||||
|       <div class="statistics-top"> |  | ||||||
|         <div class="statistics-top__item"> |  | ||||||
|           <span>返乡人数</span> |  | ||||||
|           <h2 style="color: #2266FF;">{{ info.total }}</h2> |  | ||||||
|         </div> |  | ||||||
|         <div class="statistics-top__item"> |  | ||||||
|           <span>今日新增返乡</span> |  | ||||||
|           <h2 style="color: #22AA99;">{{ info.today }}</h2> |  | ||||||
|         </div> |  | ||||||
|         <div class="statistics-top__item"> |  | ||||||
|           <span>异常人数</span> |  | ||||||
|           <h2 style="color: #F8B425">{{ info.unusual }}</h2> |  | ||||||
|         </div> |  | ||||||
|         <div class="statistics-top__item"> |  | ||||||
|           <span>今日异常人数</span> |  | ||||||
|           <h2 style="color: red">{{ info.todayUnusual }}</h2> |  | ||||||
|         </div> |  | ||||||
|         <div class="statistics-top__item"> |  | ||||||
|           <span>异常处理</span> |  | ||||||
|           <h2 style="color: red">{{ info.release }}</h2> |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|       <div class="content"> |  | ||||||
|         <ai-search-bar bottomBorder> |  | ||||||
|           <template #left> |  | ||||||
|             <ai-select |  | ||||||
|               v-model="search.status" |  | ||||||
|               clearable |  | ||||||
|               placeholder="请选择健康状态" |  | ||||||
|               :selectList="dictList" |  | ||||||
|               @change="search.current = 1, getList()"> |  | ||||||
|             </ai-select> |  | ||||||
|             <ai-download :instance="instance" url="/app/appepidemicbackhomerecord/export" :params="param" fileName="返乡登记" :disabled="tableData.length == 0"> |  | ||||||
|               <el-button icon="iconfont iconExported" :disabled="tableData.length == 0">导出</el-button> |  | ||||||
|             </ai-download> |  | ||||||
|           </template> |  | ||||||
|           <template #right> |  | ||||||
|             <el-input |  | ||||||
|               v-model="search.name" |  | ||||||
|               size="small" |  | ||||||
|               placeholder="请输入姓名" |  | ||||||
|               clearable |  | ||||||
|               v-throttle="() => {search.current = 1, getList()}" |  | ||||||
|               @clear="search.current = 1, search.name = '', getList()" |  | ||||||
|               suffix-icon="iconfont iconSearch"> |  | ||||||
|             </el-input> |  | ||||||
|           </template> |  | ||||||
|         </ai-search-bar> |  | ||||||
|         <ai-table |  | ||||||
|           :tableData="tableData" |  | ||||||
|           :col-configs="colConfigs" |  | ||||||
|           :total="total" |  | ||||||
|           v-loading="loading" |  | ||||||
|           style="margin-top: 16px;" |  | ||||||
|           :current.sync="search.current" |  | ||||||
|           :size.sync="search.size" |  | ||||||
|           @getList="getList"> |  | ||||||
|           <el-table-column slot="options" width="140px" fixed="right" label="操作" align="center"> |  | ||||||
|             <template slot-scope="{ row }"> |  | ||||||
|               <div class="table-options"> |  | ||||||
|                 <el-button type="text" @click="toDetail(row.id)">详情</el-button> |  | ||||||
|                 <el-button type="text" @click="remove(row.id)">删除</el-button> |  | ||||||
|               </div> |  | ||||||
|             </template> |  | ||||||
|           </el-table-column> |  | ||||||
|         </ai-table> |  | ||||||
|       </div> |  | ||||||
|     </template> |  | ||||||
|   </ai-list> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   import { mapState } from 'vuex' |  | ||||||
|   export default { |  | ||||||
|     name: 'List', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object, |  | ||||||
|       areaId: String |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data () { |  | ||||||
|       return { |  | ||||||
|         search: { |  | ||||||
|           current: 1, |  | ||||||
|           size: 10, |  | ||||||
|           name: '', |  | ||||||
|           status: '' |  | ||||||
|         }, |  | ||||||
|         dictList: [{ |  | ||||||
|           dictName: '异常', |  | ||||||
|           dictValue: '0' |  | ||||||
|         }, { |  | ||||||
|           dictName: '正常', |  | ||||||
|           dictValue: '1' |  | ||||||
|         }], |  | ||||||
|         info: {}, |  | ||||||
|         colConfigs: [ |  | ||||||
|           { prop: 'name', label: '姓名' }, |  | ||||||
|           { prop: 'phone', align: 'center', label: '手机号码' }, |  | ||||||
|           { prop: 'startTime', align: 'center', label: '出发时间', format: v => v.substr(0, v.length - 3) }, |  | ||||||
|           { |  | ||||||
|             prop: 'startAreaName', |  | ||||||
|             align: 'center', |  | ||||||
|             label: '出发地区' |  | ||||||
|           }, |  | ||||||
|           { prop: 'arriveTime', align: 'center', label: '到达时间', format: v => v.substr(0, v.length - 3) }, |  | ||||||
|           { |  | ||||||
|             prop: 'arriveAreaName', |  | ||||||
|             align: 'center', |  | ||||||
|             label: '到达地区' |  | ||||||
|           }, |  | ||||||
|           { prop: 'checkTime', align: 'center', label: '核酸日期', format: v => v.split(' ')[0] }, |  | ||||||
|           { |  | ||||||
|             prop: 'status', |  | ||||||
|             align: 'center', |  | ||||||
|             label: '健康状态', |  | ||||||
|             render: (h, {row}) => { |  | ||||||
|               return h('span', { |  | ||||||
|                 style: { |  | ||||||
|                   color: row.status === '0' ? 'red' : '#333' |  | ||||||
|                 } |  | ||||||
|               }, row.status === '0' ? '异常' : '正常') |  | ||||||
|             } |  | ||||||
|           } |  | ||||||
|         ], |  | ||||||
|         ids: [], |  | ||||||
|         tableData: [], |  | ||||||
|         total: 0, |  | ||||||
|         loading: false, |  | ||||||
|         disabledLevel: 0 |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     computed: { |  | ||||||
|       ...mapState(['user']), |  | ||||||
|  |  | ||||||
|       param () { |  | ||||||
|         return this.search |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     created () { |  | ||||||
|       this.disabledLevel = this.user.info.areaList.length - 1 |  | ||||||
|       this.loading = true |  | ||||||
|       this.dict.load(['marriageType', 'marriagePersonType', 'modeType']).then(() => { |  | ||||||
|         this.getList() |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       getList () { |  | ||||||
|         this.instance.post(`/app/appepidemicbackhomerecord/list`, null, { |  | ||||||
|           params: { |  | ||||||
|             ...this.search, |  | ||||||
|             arriveAreaId: this.areaId |  | ||||||
|           } |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.tableData = res.data.records |  | ||||||
|             this.total = res.data.total |  | ||||||
|             this.loading = false |  | ||||||
|           } else { |  | ||||||
|             this.loading = false |  | ||||||
|           } |  | ||||||
|         }).catch(() => { |  | ||||||
|           this.loading = false |  | ||||||
|         }) |  | ||||||
|  |  | ||||||
|         this.getTotalInfo() |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       toDetail (id) { |  | ||||||
|         this.$emit('change', { |  | ||||||
|           type: 'Detail', |  | ||||||
|           params: { |  | ||||||
|             id: id || '' |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       changeArea () { |  | ||||||
|         this.search.current = 1 |  | ||||||
|  |  | ||||||
|         this.$nextTick(() => { |  | ||||||
|           this.getList() |  | ||||||
|           this.getTotalInfo() |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       remove(id) { |  | ||||||
|         this.$confirm('确定删除该数据?').then(() => { |  | ||||||
|           this.instance.post(`/app/appepidemicbackhomerecord/delete?ids=${id}`).then(res => { |  | ||||||
|             if (res.code == 0) { |  | ||||||
|               this.$message.success('删除成功!') |  | ||||||
|               this.getTotalInfo() |  | ||||||
|               this.getList() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|  |  | ||||||
|       getTotalInfo () { |  | ||||||
|         this.instance.post(`/app/appepidemicbackhomerecord/statistic`, null, { |  | ||||||
|           params: { |  | ||||||
|             areaId: this.search.arriveAreaId |  | ||||||
|           } |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.info = res.data |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
|   .list { |  | ||||||
|     :deep( .ai-list__content ){ |  | ||||||
|       padding: 0!important; |  | ||||||
|  |  | ||||||
|       .ai-list__content--right-wrapper { |  | ||||||
|         background: transparent!important; |  | ||||||
|         box-shadow: none!important; |  | ||||||
|         margin: 0!important; |  | ||||||
|         padding: 0 0 0!important; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     .statistics-top { |  | ||||||
|       display: flex; |  | ||||||
|       align-items: center; |  | ||||||
|       margin-bottom: 20px; |  | ||||||
|  |  | ||||||
|       & > div { |  | ||||||
|         flex: 1; |  | ||||||
|         height: 96px; |  | ||||||
|         line-height: 1; |  | ||||||
|         margin-right: 20px; |  | ||||||
|         padding: 16px 24px; |  | ||||||
|         background: #FFFFFF; |  | ||||||
|         box-shadow: 0px 4px 6px -2px rgba(15, 15, 21, 0.15); |  | ||||||
|         border-radius: 4px; |  | ||||||
|  |  | ||||||
|         &:last-child { |  | ||||||
|           margin-right: 0; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         h3 { |  | ||||||
|           font-size: 24px; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         span { |  | ||||||
|           display: block; |  | ||||||
|           margin-bottom: 16px; |  | ||||||
|           color: #888888; |  | ||||||
|           font-size: 16px; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .content { |  | ||||||
|       padding: 16px; |  | ||||||
|       background: #FFFFFF; |  | ||||||
|       box-shadow: 0px 4px 6px -2px rgba(15, 15, 21, 0.15); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </style> |  | ||||||
| @@ -1,65 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <div class="doc-circulation ailist-wrapper"> |  | ||||||
|     <keep-alive :include="['List']"> |  | ||||||
|       <component ref="component" :moduleName="moduleName" :moduleId="moduleId" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component> |  | ||||||
|     </keep-alive> |  | ||||||
|   </div> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   import List from './components/List' |  | ||||||
|   import Add from './components/Add' |  | ||||||
|  |  | ||||||
|   export default { |  | ||||||
|     name: 'AppRiskArea', |  | ||||||
|     label: '风险配置', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data () { |  | ||||||
|       return { |  | ||||||
|         component: 'List', |  | ||||||
|         params: {}, |  | ||||||
|         moduleId: '', |  | ||||||
|         include: [], |  | ||||||
|         moduleName: '' |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     components: { |  | ||||||
|       Add, |  | ||||||
|       List |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       onChange (data) { |  | ||||||
|         if (data.type === 'Add') { |  | ||||||
|           this.component = 'Add' |  | ||||||
|           this.params = data.params |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (data.type === 'list') { |  | ||||||
|           this.component = 'List' |  | ||||||
|           this.params = data.params |  | ||||||
|  |  | ||||||
|           this.$nextTick(() => { |  | ||||||
|             if (data.isRefresh) { |  | ||||||
|               this.$refs.component.getList() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss"> |  | ||||||
|   .doc-circulation { |  | ||||||
|     height: 100%; |  | ||||||
|     background: #F3F6F9; |  | ||||||
|     overflow: auto; |  | ||||||
|   } |  | ||||||
| </style> |  | ||||||
| @@ -1,154 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <ai-detail class="content-add"> |  | ||||||
|     <template slot="title"> |  | ||||||
|       <ai-title :title="params.id ? '编辑风险区域' : '添加风险区域'" isShowBack isShowBottomBorder @onBackClick="cancel(false)"> |  | ||||||
|       </ai-title> |  | ||||||
|     </template> |  | ||||||
|     <template slot="content"> |  | ||||||
|       <ai-card title="基本信息"> |  | ||||||
|         <template #content> |  | ||||||
|           <el-form class="ai-form" :model="form" label-width="120px" ref="form"> |  | ||||||
|             <el-form-item prop="areaId" style="width: 100%;" label="选择地区" :rules="[{required: true, message: '请选择地区', trigger: 'change'}]"> |  | ||||||
|               <ai-area-select clearable @fullname="v => form.areaName = v" always-show :instance="instance" v-model="form.areaId"></ai-area-select> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="风险等级" style="width: 100%;" prop="level" :rules="[{required: true, message: '请选择风险等级', trigger: 'change'}]"> |  | ||||||
|               <ai-select |  | ||||||
|                 v-model="form.level" |  | ||||||
|                 clearable |  | ||||||
|                 placeholder="请选择风险等级" |  | ||||||
|                 :selectList="dict.getDict('epidemicDangerousAreaLevel')"> |  | ||||||
|               </ai-select> |  | ||||||
|             </el-form-item> |  | ||||||
|           </el-form> |  | ||||||
|         </template> |  | ||||||
|       </ai-card> |  | ||||||
|     </template> |  | ||||||
|     <template #footer> |  | ||||||
|       <el-button @click="cancel">取消</el-button> |  | ||||||
|       <el-button type="primary" @click="confirm">提交</el-button> |  | ||||||
|     </template> |  | ||||||
|   </ai-detail> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   import { mapState } from 'vuex' |  | ||||||
|   export default { |  | ||||||
|     name: 'Add', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object, |  | ||||||
|       params: Object, |  | ||||||
|       moduleName: String |  | ||||||
|     }, |  | ||||||
|     data () { |  | ||||||
|       return { |  | ||||||
|         info: {}, |  | ||||||
|         form: { |  | ||||||
|           level: '', |  | ||||||
|           areaId: '', |  | ||||||
|           areaName: '' |  | ||||||
|         }, |  | ||||||
|         id: '' |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     computed: { |  | ||||||
|       ...mapState(['user']) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     created () { |  | ||||||
|       this.dict.load('epidemicDangerousAreaLevel').then(() => { |  | ||||||
|         if (this.params && this.params.id) { |  | ||||||
|           this.id = this.params.id |  | ||||||
|           this.getInfo(this.params.id) |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       getInfo (id) { |  | ||||||
|         this.instance.post(`/app/appepidemicdangerousarea/queryDetailById?id=${id}`).then(res => { |  | ||||||
|           if (res.code === 0) { |  | ||||||
|             this.form = res.data |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       confirm () { |  | ||||||
|         this.$refs.form.validate((valid) => { |  | ||||||
|           if (valid) { |  | ||||||
|             this.instance.post(`/app/appepidemicdangerousarea/addOrUpdate`, { |  | ||||||
|               ...this.form |  | ||||||
|             }).then(res => { |  | ||||||
|               if (res.code == 0) { |  | ||||||
|                 this.$message.success('提交成功') |  | ||||||
|                 setTimeout(() => { |  | ||||||
|                   this.cancel(true) |  | ||||||
|                 }, 600) |  | ||||||
|               } |  | ||||||
|             }) |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       cancel (isRefresh) { |  | ||||||
|         this.$emit('change', { |  | ||||||
|           type: 'list', |  | ||||||
|           isRefresh: !!isRefresh |  | ||||||
|         }) |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
|   .content-add { |  | ||||||
|     .video { |  | ||||||
|       width: 640px; |  | ||||||
|       height: 360px; |  | ||||||
|       border-radius: 4px; |  | ||||||
|       border: 1px dashed #D0D4DC; |  | ||||||
|       display: flex; |  | ||||||
|       flex-direction: column; |  | ||||||
|       align-items: center; |  | ||||||
|       justify-content: center; |  | ||||||
|  |  | ||||||
|       .icon { |  | ||||||
|         display: flex; |  | ||||||
|         flex-direction: column; |  | ||||||
|         align-items: center; |  | ||||||
|         justify-content: center; |  | ||||||
|  |  | ||||||
|         span:nth-child(2) { |  | ||||||
|           display: inline-block; |  | ||||||
|           font-size: 16px; |  | ||||||
|           color: #333333; |  | ||||||
|           line-height: 30px; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         .iconfont { |  | ||||||
|           display: inline-block; |  | ||||||
|           font-size: 40px; |  | ||||||
|           color: #2266FF; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .tips { |  | ||||||
|         display: inline-block; |  | ||||||
|         font-size: 12px; |  | ||||||
|         color: #999999; |  | ||||||
|         line-height: 26px; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .video-com { |  | ||||||
|       width: 640px; |  | ||||||
|       height: 360px; |  | ||||||
|       background: rgba(0, 0, 0, 0.5); |  | ||||||
|       border-radius: 2px; |  | ||||||
|       border: 1px solid #D0D4DC; |  | ||||||
|       margin-top: -40px; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </style> |  | ||||||
| @@ -1,141 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <ai-list class="notice"> |  | ||||||
|     <template slot="title"> |  | ||||||
|       <ai-title title="风险区域配置" isShowBottomBorder></ai-title> |  | ||||||
|     </template> |  | ||||||
|     <template slot="content"> |  | ||||||
|       <ai-search-bar class="search-bar"> |  | ||||||
|         <template #left> |  | ||||||
|           <ai-select |  | ||||||
|             v-model="search.level" |  | ||||||
|             clearable |  | ||||||
|             placeholder="请选择风险等级" |  | ||||||
|             :selectList="dict.getDict('epidemicDangerousAreaLevel')" |  | ||||||
|             @change="search.current = 1, getList()"> |  | ||||||
|           </ai-select> |  | ||||||
|           <el-button size="small" type="primary" icon="iconfont iconAdd" @click="toAdd('')">添加</el-button> |  | ||||||
|         </template> |  | ||||||
|         <template #right> |  | ||||||
|           <el-input |  | ||||||
|             v-model="search.province" |  | ||||||
|             class="search-input" |  | ||||||
|             size="small" |  | ||||||
|             v-throttle="() => {search.current = 1, getList()}" |  | ||||||
|             placeholder="省级名称/市级名称/区级名称" |  | ||||||
|             clearable |  | ||||||
|             @clear="search.current = 1, search.province = '', getList()" |  | ||||||
|             suffix-icon="iconfont iconSearch"> |  | ||||||
|           </el-input> |  | ||||||
|         </template> |  | ||||||
|       </ai-search-bar> |  | ||||||
|       <ai-table |  | ||||||
|         :tableData="tableData" |  | ||||||
|         :col-configs="colConfigs" |  | ||||||
|         :total="total" |  | ||||||
|         style="margin-top: 6px;" |  | ||||||
|         :current.sync="search.current" |  | ||||||
|         :size.sync="search.size" |  | ||||||
|         @getList="getList"> |  | ||||||
|         <el-table-column slot="options" width="140px" fixed="right" label="操作" align="center"> |  | ||||||
|           <template slot-scope="{ row }"> |  | ||||||
|             <div class="table-options"> |  | ||||||
|               <el-button type="text" @click="toAdd(row.id)">编辑</el-button> |  | ||||||
|               <el-button type="text" @click="remove(row.id)">删除</el-button> |  | ||||||
|             </div> |  | ||||||
|           </template> |  | ||||||
|         </el-table-column> |  | ||||||
|       </ai-table> |  | ||||||
|     </template> |  | ||||||
|   </ai-list> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   import { mapState } from 'vuex' |  | ||||||
|   export default { |  | ||||||
|     name: 'List', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object, |  | ||||||
|       moduleName: String |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data() { |  | ||||||
|       return { |  | ||||||
|         search: { |  | ||||||
|           current: 1, |  | ||||||
|           size: 10, |  | ||||||
|           level: '', |  | ||||||
|           province: '' |  | ||||||
|         }, |  | ||||||
|         currIndex: -1, |  | ||||||
|         areaList: [], |  | ||||||
|         total: 10, |  | ||||||
|         colConfigs: [ |  | ||||||
|           { prop: 'province',  label: '省级', align: 'left', width: '200px' }, |  | ||||||
|           { prop: 'city', label: '市级', align: 'center' }, |  | ||||||
|           { prop: 'district', label: '区级', align: 'center' }, |  | ||||||
|           { prop: 'town', label: '镇级', align: 'center' }, |  | ||||||
|           { prop: 'village', label: '村级', align: 'center' }, |  | ||||||
|           { prop: 'level', label: '等级', align: 'center', format: v => this.dict.getLabel('epidemicDangerousAreaLevel', v) }, |  | ||||||
|           { prop: 'createTime', label: '设置时间', align: 'center' }, |  | ||||||
|           { prop: 'createUserName', label: '添加人', align: 'center' }, |  | ||||||
|           { slot: 'options', label: '操作', align: 'center' } |  | ||||||
|         ], |  | ||||||
|         areaName: '', |  | ||||||
|         unitName: '', |  | ||||||
|         tableData: [] |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     computed: { |  | ||||||
|       ...mapState(['user']) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     created() { |  | ||||||
|       this.dict.load('epidemicDangerousAreaLevel').then(() => { |  | ||||||
|         this.getList() |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       getList() { |  | ||||||
|         this.instance.post(`/app/appepidemicdangerousarea/list`, null, { |  | ||||||
|           params: { |  | ||||||
|             ...this.search |  | ||||||
|           } |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.tableData = res.data.records |  | ||||||
|             this.total = res.data.total |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       remove(id) { |  | ||||||
|         this.$confirm('确定删除该数据?').then(() => { |  | ||||||
|           this.instance.post(`/app/appepidemicdangerousarea/delete?ids=${id}`).then(res => { |  | ||||||
|             if (res.code == 0) { |  | ||||||
|               this.$message.success('删除成功!') |  | ||||||
|               this.getList() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       toAdd(id) { |  | ||||||
|         this.$emit('change', { |  | ||||||
|           type: 'Add', |  | ||||||
|           params: { |  | ||||||
|             id: id || '' |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
|   .notice { |  | ||||||
|   } |  | ||||||
| </style> |  | ||||||
| @@ -1,206 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <section class="AppVaccination"> |  | ||||||
|     <ai-list v-if="!showDetail"> |  | ||||||
|       <ai-title slot="title" title="疫苗接种" isShowBottomBorder isShowArea v-model="areaId" :instance="instance" |  | ||||||
|                 @change="page.current=1,getTableData()"/> |  | ||||||
|       <template #blank> |  | ||||||
|         <el-row type="flex"> |  | ||||||
|           <div class="dataPane" v-for="(op,i) in dataPanes" :key="i"> |  | ||||||
|             {{ [op.label, op.v].join(" ") }} |  | ||||||
|           </div> |  | ||||||
|         </el-row> |  | ||||||
|         <div class="mainPane"> |  | ||||||
|           <ai-search-bar> |  | ||||||
|             <template #left> |  | ||||||
|               <ai-select placeholder="接种状况" v-model="search.inoculationType" @change="page.current=1,getTableData()" |  | ||||||
|                          :selectList="dict.getDict('vaccineInoculationType')"/> |  | ||||||
|             </template> |  | ||||||
|             <template #right> |  | ||||||
|               <el-input placeholder="姓名/身份证/联系方式" |  | ||||||
|                         v-model="search.name" |  | ||||||
|                         size="small" |  | ||||||
|                         clearable |  | ||||||
|                         @clear="page.current = 1,search.name = '', getTableData()" |  | ||||||
|                         v-throttle="() => {page.current = 1, getTableData()}" |  | ||||||
|                         suffix-icon="iconfont iconSearch"/> |  | ||||||
|             </template> |  | ||||||
|           </ai-search-bar> |  | ||||||
|           <ai-search-bar> |  | ||||||
|             <template #left> |  | ||||||
|               <el-button type="primary" icon="iconfont iconAdd" @click="$router.push({hash:'#add'})">添加</el-button> |  | ||||||
|               <el-button icon="iconfont iconDelete" :disabled="!ids.length" @click="handleDelete(ids)">删除</el-button> |  | ||||||
|             </template> |  | ||||||
|             <template #right> |  | ||||||
|               <ai-import :instance="instance" :dict="dict" name="疫苗接种" suffixName="xlsx" |  | ||||||
|                          type="appvaccineinoculationuser" @onSuccess="resetSearch"/> |  | ||||||
|               <ai-download url="/app/appvaccineinoculationuser/export" :params="{...search,areaId,ids:ids.toString()}" |  | ||||||
|                            :instance="instance" fileName="疫苗接种导出文件"/> |  | ||||||
|             </template> |  | ||||||
|           </ai-search-bar> |  | ||||||
|           <ai-table :tableData="tableData" :colConfigs="colConfigs" :total="page.total" :current.sync="page.current" |  | ||||||
|                     :size.sync="page.size" @getList="getTableData" :dict="dict" |  | ||||||
|                     @selection-change="v=>ids=v.map(e=>e.id)"> |  | ||||||
|             <el-table-column slot="vaccinationDate" label="接种日期" align="center" class-name="vaccinationDate"> |  | ||||||
|               <el-table-column label="第一次" align="center" prop="firstDate"/> |  | ||||||
|               <el-table-column label="第二次" align="center" prop="secondDate"/> |  | ||||||
|               <el-table-column label="第三次" align="center" prop="thirdDate"/> |  | ||||||
|             </el-table-column> |  | ||||||
|             <el-table-column slot="options" label="操作" align="center" fixed="right"> |  | ||||||
|               <template slot-scope="{row:{id}}"> |  | ||||||
|                 <el-button type="text" @click="$router.push({hash:'#add',query:{id}})">编辑</el-button> |  | ||||||
|                 <el-button type="text" @click="handleDelete(id)">删除</el-button> |  | ||||||
|               </template> |  | ||||||
|             </el-table-column> |  | ||||||
|           </ai-table> |  | ||||||
|         </div> |  | ||||||
|       </template> |  | ||||||
|     </ai-list> |  | ||||||
|     <add-vaccination v-else :dict="dict" :instance="instance"/> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| import {mapState} from "vuex"; |  | ||||||
| import AddVaccination from "./addVaccination"; |  | ||||||
| import {ID} from "dui/lib/js/utils"; |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "AppVaccination", |  | ||||||
|   components: {AddVaccination}, |  | ||||||
|   label: "疫苗接种", |  | ||||||
|   provide() { |  | ||||||
|     return { |  | ||||||
|       top: this |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function, |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       areaId: "", |  | ||||||
|       page: {current: 1, size: 10, total: 0}, |  | ||||||
|       search: {inoculationType: "", name: ""}, |  | ||||||
|       ids: [], |  | ||||||
|       tableData: [], |  | ||||||
|       staData: {} |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     ...mapState(['user']), |  | ||||||
|     showDetail() { |  | ||||||
|       return this.$route.hash == "#add" |  | ||||||
|     }, |  | ||||||
|     dataPanes() { |  | ||||||
|       return [ |  | ||||||
|         {label: "总接种人数", v: this.staData.zjzrs || 0}, |  | ||||||
|         {label: "已接种第一针人数", v: this.staData.yjzdyzrs || 0}, |  | ||||||
|         {label: "已接种第二针人数", v: this.staData.yjzdezrs || 0}, |  | ||||||
|         {label: "已接种第三针人数", v: this.staData.yjzdszrs || 0}, |  | ||||||
|       ] |  | ||||||
|     }, |  | ||||||
|     colConfigs() { |  | ||||||
|       return [ |  | ||||||
|         {type: "selection", align: 'center'}, |  | ||||||
|         {label: "姓名", prop: "name", align: 'center'}, |  | ||||||
|         {label: "性别", prop: "sex", dict: 'sex', align: 'center'}, |  | ||||||
|         {label: "出生日期", prop: "birthday", align: 'center'}, |  | ||||||
|         { |  | ||||||
|           label: "身份证号", width: "160px", align: 'center', |  | ||||||
|           render: (h, {row}) => h('span', null, ID.hideId(row.idNumber)) |  | ||||||
|         }, |  | ||||||
|         {label: "所属地区", prop: "areaName", align: 'center'}, |  | ||||||
|         {label: "住址", prop: "address", width: "200px", align: 'center'}, |  | ||||||
|         {label: "联系方式", prop: "phone", align: 'center'}, |  | ||||||
|         {slot: 'vaccinationDate'}, |  | ||||||
|         {slot: "options"}, |  | ||||||
|       ] |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.areaId = JSON.parse(JSON.stringify(this.user.info.areaId)) |  | ||||||
|     this.dict.load('sex', 'vaccineInoculationType') |  | ||||||
|     this.getTableData() |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     getStaData() { |  | ||||||
|       this.instance.post(`/app/appvaccineinoculationuser/countByAreaId`, null, { |  | ||||||
|         params: {areaId: this.areaId} |  | ||||||
|       }).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           this.staData = res.data |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     getTableData() { |  | ||||||
|       this.page.current == 1 && this.getStaData() |  | ||||||
|       this.instance.post(`/app/appvaccineinoculationuser/list`, null, { |  | ||||||
|         params: {...this.search, ...this.page, areaId: this.areaId} |  | ||||||
|       }).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           this.tableData = res.data.records |  | ||||||
|           this.page.total = res.data.total |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     handleDelete(ids) { |  | ||||||
|       ids = ids?.toString() |  | ||||||
|       this.$confirm("确定要删除该条数据吗?").then(() => { |  | ||||||
|         this.instance.post(`/app/appvaccineinoculationuser/delete`, null, { |  | ||||||
|           params: {ids} |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res?.code == 0) { |  | ||||||
|             this.$message.success("删除成功!"); |  | ||||||
|             this.getTableData(); |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }).catch(() => 0) |  | ||||||
|     }, |  | ||||||
|     resetSearch() { |  | ||||||
|       this.page.current = 1 |  | ||||||
|       this.search = {} |  | ||||||
|       this.getTableData() |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
| .AppVaccination { |  | ||||||
|   height: 100%; |  | ||||||
|  |  | ||||||
|   :deep( .dataPane ){ |  | ||||||
|     flex: 1; |  | ||||||
|     min-width: 0; |  | ||||||
|     background: #FFFFFF; |  | ||||||
|     box-shadow: 0 4px 6px -2px rgba(15, 15, 21, 0.15); |  | ||||||
|     border-radius: 2px; |  | ||||||
|     margin-bottom: 16px; |  | ||||||
|     margin-right: 16px; |  | ||||||
|     display: flex; |  | ||||||
|     align-items: center; |  | ||||||
|     justify-content: center; |  | ||||||
|     height: 60px; |  | ||||||
|  |  | ||||||
|     &:last-of-type { |  | ||||||
|       margin-right: 0; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   :deep( .mainPane ){ |  | ||||||
|     background: #fff; |  | ||||||
|     padding: 12px 16px; |  | ||||||
|     box-shadow: 0 4px 6px -2px rgba(15, 15, 21, 0.15); |  | ||||||
|  |  | ||||||
|     .vaccinationDate { |  | ||||||
|       border-bottom: 1px solid #D0D4DC; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .ai-table__header { |  | ||||||
|       padding: 2px 0; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,236 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <section class="addVaccination"> |  | ||||||
|     <ai-detail> |  | ||||||
|       <ai-title slot="title" :title="addTitle" isShowBottomBorder |  | ||||||
|                 isShowBack @onBackClick="back"/> |  | ||||||
|       <template #content> |  | ||||||
|         <el-form size="small" :model="form" ref="vaccinationForm" :rules="rules" label-width="100px"> |  | ||||||
|           <ai-card title="基本信息"> |  | ||||||
|             <template #content> |  | ||||||
|               <el-form-item label="受种人姓名" prop="name"> |  | ||||||
|                 <el-row type="flex" align="middle"> |  | ||||||
|                   <el-input placeholder="请输入" v-model="form.name" :disabled="isEdit" clearable |  | ||||||
|                             style="margin-right: 8px"/> |  | ||||||
|                   <ai-person-select v-if="!isEdit" :instance="instance" @selectPerson="handleSelectPerson"/> |  | ||||||
|                 </el-row> |  | ||||||
|               </el-form-item> |  | ||||||
|               <el-form-item label="身份证号码" prop="idNumber"> |  | ||||||
|                 <ai-id v-model="form.idNumber" @change="getInfoByIdNumber" :disabled="isEdit"/> |  | ||||||
|               </el-form-item> |  | ||||||
|               <el-form-item label="性别" prop="sex"> |  | ||||||
|                 <ai-select disabled v-model="form.sex" :selectList="dict.getDict('sex')"/> |  | ||||||
|               </el-form-item> |  | ||||||
|               <el-form-item label="出生日期" prop="birthday"> |  | ||||||
|                 <el-date-picker v-model="form.birthday" type="date" disabled/> |  | ||||||
|               </el-form-item> |  | ||||||
|               <el-form-item label="联系方式" prop="phone"> |  | ||||||
|                 <el-input v-model="form.phone" placeholder="请输入"/> |  | ||||||
|               </el-form-item> |  | ||||||
|               <el-form-item label="所属地区" isLine prop="areaId"> |  | ||||||
|                 <ai-area-select :instance="instance" v-model="form.areaId" always-show @name="v=>form.areaName=v"/> |  | ||||||
|               </el-form-item> |  | ||||||
|               <el-form-item label="住址" isLine prop="address"> |  | ||||||
|                 <el-input v-model="form.address" placeholder="请输入"/> |  | ||||||
|               </el-form-item> |  | ||||||
|             </template> |  | ||||||
|           </ai-card> |  | ||||||
|           <ai-card title="接种情况"> |  | ||||||
|             <template #right> |  | ||||||
|               <el-button icon="iconfont iconAdd" type="text" @click="dialog=true">添加</el-button> |  | ||||||
|             </template> |  | ||||||
|             <template #content> |  | ||||||
|               <el-form-item isLine label-width="0"> |  | ||||||
|                 <ai-table :tableData="form.detailList" :colConfigs="colConfigs" :isShowPagination="false" :dict="dict"> |  | ||||||
|                   <el-table-column slot="options" label="操作" align="center" fixed="right"> |  | ||||||
|                     <template v-slot="{row,$index}"> |  | ||||||
|                       <el-button type="text" @click="handleEdit(row,$index)">编辑</el-button> |  | ||||||
|                       <el-button type="text" @click="handleDelete($index)">删除</el-button> |  | ||||||
|                     </template> |  | ||||||
|                   </el-table-column> |  | ||||||
|                 </ai-table> |  | ||||||
|               </el-form-item> |  | ||||||
|             </template> |  | ||||||
|           </ai-card> |  | ||||||
|         </el-form> |  | ||||||
|       </template> |  | ||||||
|       <template #footer> |  | ||||||
|         <el-button @click="back">取消</el-button> |  | ||||||
|         <el-button type="primary" @click="handleSubmit">提交</el-button> |  | ||||||
|       </template> |  | ||||||
|     </ai-detail> |  | ||||||
|     <ai-dialog :visible.sync="dialog" title="接种情况" @closed="dialogForm={}" @onConfirm="handleConfirm"> |  | ||||||
|       <el-form ref="appvaccineinoculationuser" size="small" :model="dialogForm" label-width="100px" :rules="rules"> |  | ||||||
|         <el-form-item label="接种次数" prop="type"> |  | ||||||
|           <ai-select v-model="dialogForm.type" :selectList="dict.getDict('vaccineType')"/> |  | ||||||
|         </el-form-item> |  | ||||||
|         <el-form-item label="接种日期" prop="vaccinateDate"> |  | ||||||
|           <el-date-picker v-model="dialogForm.vaccinateDate" value-format="yyyy-MM-dd"/> |  | ||||||
|         </el-form-item> |  | ||||||
|         <el-form-item label="接种人员" prop="vaccinatePerson"> |  | ||||||
|           <el-input v-model="dialogForm.vaccinatePerson"/> |  | ||||||
|         </el-form-item> |  | ||||||
|         <el-form-item label="生产企业" prop="createCompany"> |  | ||||||
|           <el-input v-model="dialogForm.createCompany"/> |  | ||||||
|         </el-form-item> |  | ||||||
|         <el-form-item label="接种单位" prop="vaccinateUnit"> |  | ||||||
|           <el-input v-model="dialogForm.vaccinateUnit"/> |  | ||||||
|         </el-form-item> |  | ||||||
|       </el-form> |  | ||||||
|     </ai-dialog> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| import {mapState} from "vuex"; |  | ||||||
| import {ID} from "dui/lib/js/utils"; |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "addVaccination", |  | ||||||
|   inject: ['top'], |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       form: {detailList: []}, |  | ||||||
|       dialog: false, |  | ||||||
|       dialogForm: {} |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     ...mapState(['user']), |  | ||||||
|     isEdit() { |  | ||||||
|       return !!this.$route.query.id |  | ||||||
|     }, |  | ||||||
|     addTitle() { |  | ||||||
|       return this.isEdit ? '编辑疫苗接种人员' : '新增疫苗接种人员' |  | ||||||
|     }, |  | ||||||
|     rules() { |  | ||||||
|       return { |  | ||||||
|         vaccinateDate: {required: true, message: "请选择 接种日期"}, |  | ||||||
|         type: {required: true, message: "请选择 接种次数",}, |  | ||||||
|         areaId: [ |  | ||||||
|           {required: true, message: "请选择 所属地区"}, |  | ||||||
|           {trigger:'blur',validator: (r, v, cb) => /0{3}$/g.test(v) ? cb('请选择到村/社区') : cb()} |  | ||||||
|         ], |  | ||||||
|         name: {required: true, message: "请填写 受种人姓名"}, |  | ||||||
|         idNumber: {required: true, message: "请填写 身份号码"}, |  | ||||||
|         sex: {required: true, message: "请填写 性别"}, |  | ||||||
|         birthday: {required: true, message: "请填写 出生日期"}, |  | ||||||
|         phone: {required: true, message: "请填写 联系方式"}, |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     colConfigs() { |  | ||||||
|       return [ |  | ||||||
|         {label: "类型", align: 'center', prop: "type", dict: 'vaccineType'}, |  | ||||||
|         {label: "接种日期", align: 'center', prop: "vaccinateDate"}, |  | ||||||
|         {label: "接种人员", align: 'center', prop: "vaccinatePerson"}, |  | ||||||
|         {label: "生产企业", align: 'center', prop: "createCompany"}, |  | ||||||
|         {label: "接种单位", align: 'center', prop: "vaccinateUnit"}, |  | ||||||
|         {slot: "options"} |  | ||||||
|       ] |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     back() { |  | ||||||
|       this.$router.push({}) |  | ||||||
|     }, |  | ||||||
|     getDetail() { |  | ||||||
|       let {id} = this.$route.query |  | ||||||
|       if (id) { |  | ||||||
|         this.instance.post("/app/appvaccineinoculationuser/queryDetailById", null, { |  | ||||||
|           params: {id} |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res?.data) { |  | ||||||
|             this.form = res.data |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       } else { |  | ||||||
|         this.$set(this.form,'areaId',JSON.parse(JSON.stringify(this.top.areaId))) |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     handleSubmit() { |  | ||||||
|       this.$refs.vaccinationForm?.validate(v => { |  | ||||||
|         if (v) { |  | ||||||
|           this.instance.post("/app/appvaccineinoculationuser/addOrUpdate", this.form).then(res => { |  | ||||||
|             if (res?.code == 0) { |  | ||||||
|               this.$message.success("提交成功!") |  | ||||||
|               this.top.resetSearch() |  | ||||||
|               this.back() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     handleEdit(row, index) { |  | ||||||
|       this.dialogForm = JSON.parse(JSON.stringify({...row, index})) |  | ||||||
|       this.dialog = true |  | ||||||
|     }, |  | ||||||
|     handleConfirm() { |  | ||||||
|       this.$refs.appvaccineinoculationuser.validate(v => { |  | ||||||
|         if (v) { |  | ||||||
|           if (this.dialogForm.index > -1) { |  | ||||||
|             this.form.detailList.splice(this.dialogForm.index, 1, this.dialogForm) |  | ||||||
|           } else { |  | ||||||
|             this.form.detailList.push(this.dialogForm) |  | ||||||
|           } |  | ||||||
|           this.dialog = false |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     handleSelectPerson(v) { |  | ||||||
|       let {name, idNumber, phone, currentAreaId:areaId, currentAddress:address} = v |  | ||||||
|       this.form = {...this.form, name, idNumber, phone, areaId, address} |  | ||||||
|     }, |  | ||||||
|     getInfoByIdNumber(code) { |  | ||||||
|       if (ID.check(code)) { |  | ||||||
|         let info = new ID(code) |  | ||||||
|         this.form.sex = info.sex |  | ||||||
|         this.form.birthday = info.birthday |  | ||||||
|         this.$forceUpdate() |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     handleDelete(index) { |  | ||||||
|       this.$confirm("是否要删除该条数据?").then(() => this.form.detailList.splice(index, 1)).catch(() => 0) |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.dict.load('vaccineType') |  | ||||||
|     this.getDetail() |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
| .addVaccination { |  | ||||||
|   height: 100%; |  | ||||||
|  |  | ||||||
|   :deep( .ai-card__body), .el-form { |  | ||||||
|     display: flex; |  | ||||||
|     flex-wrap: wrap; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .ai-card { |  | ||||||
|     width: 100%; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .el-form-item { |  | ||||||
|     width: 50%; |  | ||||||
|  |  | ||||||
|     &[isLine] { |  | ||||||
|       width: 100%; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .el-date-editor { |  | ||||||
|       width: 100%; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   :deep( .el-button ){ |  | ||||||
|     .iconfont { |  | ||||||
|       color: inherit |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -49,7 +49,6 @@ | |||||||
|               <el-button type="text" @click="toDetail(row.id)">详情</el-button> |               <el-button type="text" @click="toDetail(row.id)">详情</el-button> | ||||||
|               <el-button type="text" @click="remove(row.id)">删除</el-button> |               <el-button type="text" @click="remove(row.id)">删除</el-button> | ||||||
|               <el-button type="text" @click="gag(row.createUserId, row.blacklist)">{{ row.blacklist ? '解除禁言' : '禁言' }}</el-button> |               <el-button type="text" @click="gag(row.createUserId, row.blacklist)">{{ row.blacklist ? '解除禁言' : '禁言' }}</el-button> | ||||||
|               <el-button type="text" v-if="row.status<1" @click="admin(row)">审核</el-button> |  | ||||||
|             </div> |             </div> | ||||||
|           </template> |           </template> | ||||||
|         </el-table-column> |         </el-table-column> | ||||||
| @@ -78,7 +77,7 @@ | |||||||
|         }, |         }, | ||||||
|         total: 0, |         total: 0, | ||||||
|         colConfigs: [ |         colConfigs: [ | ||||||
|           { prop: 'content',  label: '帖子内容', align: 'left' }, |           { prop: 'content',  label: '内容', align: 'left' }, | ||||||
|           { prop: 'createUserName',  label: '发帖人', align: 'center', width: '120' }, |           { prop: 'createUserName',  label: '发帖人', align: 'center', width: '120' }, | ||||||
|           { prop: 'createUserAreaName',  label: '所属地区', align: 'center' }, |           { prop: 'createUserAreaName',  label: '所属地区', align: 'center' }, | ||||||
|           { prop: 'createTime',  label: '创建时间', align: 'center' }, |           { prop: 'createTime',  label: '创建时间', align: 'center' }, | ||||||
| @@ -86,7 +85,6 @@ | |||||||
|           { prop: 'appreciateCount',  label: '点赞数', align: 'center', width: '120' }, |           { prop: 'appreciateCount',  label: '点赞数', align: 'center', width: '120' }, | ||||||
|           { prop: 'sharedCount',  label: '分享数', align: 'center', width: '120' }, |           { prop: 'sharedCount',  label: '分享数', align: 'center', width: '120' }, | ||||||
|           { prop: 'blacklist',  label: '状态', align: 'center', format: v => v ? '禁言' : '正常' }, |           { prop: 'blacklist',  label: '状态', align: 'center', format: v => v ? '禁言' : '正常' }, | ||||||
|           { prop: 'status',  label: '审核状态', align: 'center', width: '120', dict: 'auditStatus' }, |  | ||||||
|           { slot: 'options'}, |           { slot: 'options'}, | ||||||
|         ], |         ], | ||||||
|         tableData: [], |         tableData: [], | ||||||
| @@ -102,9 +100,7 @@ | |||||||
|  |  | ||||||
|     created() { |     created() { | ||||||
|       this.search.areaId = this.user.info.areaId |       this.search.areaId = this.user.info.areaId | ||||||
|       this.dict.load('auditStatus').then(() => { |  | ||||||
|       this.getList() |       this.getList() | ||||||
|       }) |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     methods: { |     methods: { | ||||||
| @@ -176,34 +172,6 @@ | |||||||
|             id: id || '' |             id: id || '' | ||||||
|           } |           } | ||||||
|         }) |         }) | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       admin(row) { |  | ||||||
|         console.log(row) |  | ||||||
|         this.$confirm('是否审核通过该条帖子?', { |  | ||||||
|           distinguishCancelAndClose: true, |  | ||||||
|           confirmButtonText: '通过', |  | ||||||
|           closeOnClickModal: true, |  | ||||||
|           cancelButtonText: '拒绝' |  | ||||||
|         }).then((e) => { |  | ||||||
|           this.instance.post(`/app/appneighborhoodassistance/examine?id=${row.id}&pass=1`).then(res => { |  | ||||||
|             if (res.code == 0) { |  | ||||||
|               this.$message.success('审核成功!') |  | ||||||
|               this.search.current = 1 |  | ||||||
|               this.getList() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         }).catch((e) => { |  | ||||||
|           if(e == 'cancel') { |  | ||||||
|             this.instance.post(`/app/appneighborhoodassistance/examine?id=${row.id}&pass=0`).then(res => { |  | ||||||
|               if (res.code == 0) { |  | ||||||
|                 this.$message.success('审核成功!') |  | ||||||
|                 this.search.current = 1 |  | ||||||
|                 this.getList() |  | ||||||
|               } |  | ||||||
|             }) |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -1,27 +1,151 @@ | |||||||
| <template> | <template> | ||||||
|   <section class="AppDictionary"> |   <section class="AppDictionary"> | ||||||
|     <component :is="currentPage" v-bind="$props"/> |     <ai-list v-if="!showDetail"> | ||||||
|  |       <ai-title slot="title" title="数据字典" isShowBottomBorder/> | ||||||
|  |       <template #content> | ||||||
|  |         <ai-search-bar> | ||||||
|  |           <template #left> | ||||||
|  |             <el-button type="primary" size="small" icon="iconfont iconAdd" @click="addDict" | ||||||
|  |                        v-if="$permissions('admin_sysdictionary_add')">添加 | ||||||
|  |             </el-button> | ||||||
|  |           </template> | ||||||
|  |           <template #right> | ||||||
|  |             <el-input size="small" v-model="search.condition" placeholder="数据项" clearable | ||||||
|  |                       @change="page.current=1,getDicts()" prefix-icon="iconfont iconSearch"/> | ||||||
|  |             <el-button type="primary" size="small" icon="iconfont iconSearch" | ||||||
|  |                        @click="page.current=1,getDicts()">查询 | ||||||
|  |             </el-button> | ||||||
|  |             <el-button size="small" icon="el-icon-refresh-right" @click="resetSearch">重置</el-button> | ||||||
|  |           </template> | ||||||
|  |         </ai-search-bar> | ||||||
|  |         <el-table size="mini" :data="dictList" header-cell-class-name="table-header" tooltip-effect="light" | ||||||
|  |                   row-class-name="table-row" cell-class-name="table-cell" @expand-change="getDictInfo"> | ||||||
|  |           <el-table-column type="expand"> | ||||||
|  |             <el-row slot-scope="{row}" type="flex" align="middle" style="flex-wrap: wrap"> | ||||||
|  |               <el-tag v-for="(op,i) in row.detail||[]" :key="i" style="margin: 4px">{{ op.dictValue }}|{{ op.dictName }} | ||||||
|  |                 {{ op.dictColor ? '| ' + op.dictColor : '' }} | ||||||
|  |               </el-tag> | ||||||
|  |             </el-row> | ||||||
|  |           </el-table-column> | ||||||
|  |           <el-table-column align="center" label="数据项" prop="code"/> | ||||||
|  |           <el-table-column align="center" label="数据项名称" prop="name"/> | ||||||
|  |           <el-table-column align="center" label="操作"> | ||||||
|  |             <div slot-scope="{row}"> | ||||||
|  |               <el-button type="text" @click="openDetail(row.id)" v-text="'编辑'" | ||||||
|  |                          v-if="$permissions('admin_sysdictionary_edit')"/> | ||||||
|  |               <el-button type="text" @click="handleDelete(row.id)" v-text="'删除'" | ||||||
|  |                          v-if="$permissions('admin_sysdictionary_del')"/> | ||||||
|  |             </div> | ||||||
|  |           </el-table-column> | ||||||
|  |           <div slot="empty" class="no-data"></div> | ||||||
|  |         </el-table> | ||||||
|  |         <div class="pagination"> | ||||||
|  |           <el-pagination background :current-page.sync="page.current" :total="page.total" | ||||||
|  |                          layout="total,prev, pager, next,sizes, jumper" | ||||||
|  |                          @size-change="handleSizeChange" | ||||||
|  |                          :page-size="page.size" | ||||||
|  |                          :page-sizes="[10, 20, 50, 100,200]" | ||||||
|  |                          @current-change="getDicts"/> | ||||||
|  |         </div> | ||||||
|  |       </template> | ||||||
|  |     </ai-list> | ||||||
|  |     <dict-detail v-else :instance="instance" :permissions="permissions"/> | ||||||
|   </section> |   </section> | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <script> | <script> | ||||||
| import DictDetail from "./dictDetail"; | import DictDetail from "./dictDetail"; | ||||||
| import DictList from "@project/xumu/AppDictionary/dictList.vue"; |  | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   name: "AppDictionary", |   name: "AppDictionary", | ||||||
|  |   components: {DictDetail}, | ||||||
|   label: "数据字典", |   label: "数据字典", | ||||||
|   props: { |   props: { | ||||||
|     instance: Function, |     instance: Function, | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function |     permissions: Function | ||||||
|   }, |   }, | ||||||
|   computed: { |   computed: { | ||||||
|     currentPage() { |     showDetail() { | ||||||
|       let {hash} = this.$route |       return this.$route.hash == "#add" | ||||||
|       return hash == "#add" ? DictDetail : DictList |  | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       page: { | ||||||
|  |         current: 1, | ||||||
|  |         total: 0, | ||||||
|  |         size: 10 | ||||||
|  |       }, | ||||||
|  |       search: { | ||||||
|  |         condition: "" | ||||||
|  |       }, | ||||||
|  |       dictList: [], | ||||||
|  |       id: '' | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     resetSearch() { | ||||||
|  |       this.page.current = 1; | ||||||
|  |       this.search.condition = ''; | ||||||
|  |       this.getDicts(); | ||||||
|  |     }, | ||||||
|  |     getDicts() { | ||||||
|  |       this.instance.post("/admin/dictionary/queryDictList", null, { | ||||||
|  |         params: { | ||||||
|  |           ...this.page, | ||||||
|  |           name: this.search.condition | ||||||
|  |         } | ||||||
|  |       }).then(res => { | ||||||
|  |         this.dictList = res.data.records.map(e => { | ||||||
|  |           return {...e, detail: []} | ||||||
|  |         }) | ||||||
|  |         this.page.total = res.data.total | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     addDict() { | ||||||
|  |       this.$router.push({hash: "#add"}) | ||||||
|  |     }, | ||||||
|  |     handleDelete(id) { | ||||||
|  |       this.$confirm("确定要删除该数据项吗?", { | ||||||
|  |         type: "error" | ||||||
|  |       }).then(() => { | ||||||
|  |         this.instance.post("/admin/dictionary/deleteDict", null, { | ||||||
|  |           params: {id} | ||||||
|  |         }).then(res => { | ||||||
|  |           if (res?.code == 0) { | ||||||
|  |             this.getDicts(); | ||||||
|  |             this.$message.success("删除成功!") | ||||||
|  |           } | ||||||
|  |         }) | ||||||
|  |       }).catch(() => 0) | ||||||
|  |     }, | ||||||
|  |     openDetail(id) { | ||||||
|  |       this.$router.push({query: {id}, hash: "#add"}) | ||||||
|  |     }, | ||||||
|  |     handleSizeChange(val) { | ||||||
|  |       this.page.size = val; | ||||||
|  |       this.getDicts(); | ||||||
|  |     }, | ||||||
|  |     getDictInfo(row) { | ||||||
|  |       if (row.detail.length) { | ||||||
|  |         row.detail = [] | ||||||
|  |       } else { | ||||||
|  |         this.getDict(row.id).then(res => { | ||||||
|  |           if (res && res.data) { | ||||||
|  |             row.detail = res.data.dictionaryDetails || [] | ||||||
|  |           } | ||||||
|  |         }) | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     getDict(dictionaryId) { | ||||||
|  |       return this.instance.post("/admin/dictionary/queryDictDetail", null, { | ||||||
|  |         params: {dictionaryId} | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  |   created() { | ||||||
|  |     this.getDicts() | ||||||
|  |   }, | ||||||
| } | } | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,142 +0,0 @@ | |||||||
| <script> |  | ||||||
| const columns = [ |  | ||||||
|   {slot: "expand"}, |  | ||||||
|   {label: "数据项", prop: "code"}, |  | ||||||
|   {label: "数据项名称", prop: "name"}, |  | ||||||
| ] |  | ||||||
| export default { |  | ||||||
|   name: "dictList", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       columns, |  | ||||||
|       page: { |  | ||||||
|         current: 1, |  | ||||||
|         total: 0, |  | ||||||
|         size: 10 |  | ||||||
|       }, |  | ||||||
|       search: { |  | ||||||
|         condition: "" |  | ||||||
|       }, |  | ||||||
|       dictList: [], |  | ||||||
|       id: '' |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     resetSearch() { |  | ||||||
|       this.page.current = 1; |  | ||||||
|       this.search.condition = ''; |  | ||||||
|       this.getDicts(); |  | ||||||
|     }, |  | ||||||
|     getDicts() { |  | ||||||
|       this.instance.post("/admin/dictionary/queryDictList", null, { |  | ||||||
|         params: { |  | ||||||
|           ...this.page, |  | ||||||
|           name: this.search.condition |  | ||||||
|         } |  | ||||||
|       }).then(res => { |  | ||||||
|         this.dictList = res.data.records.map(e => { |  | ||||||
|           return {...e, detail: []} |  | ||||||
|         }) |  | ||||||
|         this.page.total = res.data.total |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     addDict() { |  | ||||||
|       this.$router.push({hash: "#add"}) |  | ||||||
|     }, |  | ||||||
|     handleDelete(id) { |  | ||||||
|       this.$confirm("确定要删除该数据项吗?", { |  | ||||||
|         type: "error" |  | ||||||
|       }).then(() => { |  | ||||||
|         this.instance.post("/admin/dictionary/deleteDict", null, { |  | ||||||
|           params: {id} |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res?.code == 0) { |  | ||||||
|             this.getDicts(); |  | ||||||
|             this.$message.success("删除成功!") |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }).catch(() => 0) |  | ||||||
|     }, |  | ||||||
|     openDetail(id) { |  | ||||||
|       this.$router.push({query: {id}, hash: "#add"}) |  | ||||||
|     }, |  | ||||||
|     handleSizeChange(val) { |  | ||||||
|       this.page.size = val; |  | ||||||
|       this.getDicts(); |  | ||||||
|     }, |  | ||||||
|     getDictInfo(row) { |  | ||||||
|       if (row.detail.length) { |  | ||||||
|         row.detail = [] |  | ||||||
|       } else { |  | ||||||
|         this.getDict(row.id).then(res => { |  | ||||||
|           if (res && res.data) { |  | ||||||
|             row.detail = res.data.dictionaryDetails || [] |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     getDict(dictionaryId) { |  | ||||||
|       return this.instance.post("/admin/dictionary/queryDictDetail", null, { |  | ||||||
|         params: {dictionaryId} |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.getDicts() |  | ||||||
|   }, |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
| <template> |  | ||||||
|   <section class="dictList"> |  | ||||||
|     <ai-list> |  | ||||||
|       <ai-title slot="title" title="数据字典" isShowBottomBorder/> |  | ||||||
|       <template #content> |  | ||||||
|         <ai-search-bar> |  | ||||||
|           <template #left> |  | ||||||
|             <el-button type="primary" size="small" icon="iconfont iconAdd" @click="addDict" |  | ||||||
|                        v-if="$permissions('admin_sysdictionary_add')">添加 |  | ||||||
|             </el-button> |  | ||||||
|           </template> |  | ||||||
|           <template #right> |  | ||||||
|             <el-input size="small" v-model="search.condition" placeholder="数据项" clearable |  | ||||||
|                       @change="page.current=1,getDicts()" prefix-icon="iconfont iconSearch"/> |  | ||||||
|             <el-button type="primary" size="small" icon="iconfont iconSearch" |  | ||||||
|                        @click="page.current=1,getDicts()">查询 |  | ||||||
|             </el-button> |  | ||||||
|             <el-button size="small" icon="el-icon-refresh-right" @click="resetSearch">重置</el-button> |  | ||||||
|           </template> |  | ||||||
|         </ai-search-bar> |  | ||||||
|         <ai-table :tableData="dictList" :colConfigs="columns" :dict="dict" @getList="getDicts" |  | ||||||
|                   :total="page.total" :current.sync="page.current" :size.sync="page.size" :page-sizes="[10, 20, 50, 100,200]" |  | ||||||
|                   @expand-change="getDictInfo"> |  | ||||||
|           <el-table-column slot="expand" type="expand"> |  | ||||||
|             <template slot-scope="{row}"> |  | ||||||
|               <div class="flex" style="gap:4px"> |  | ||||||
|                 <el-tag v-for="(op,i) in row.detail||[]" :key="i">{{ [op.dictValue, op.dictName, op.dictColor].filter(Boolean).join("|") }}</el-tag> |  | ||||||
|               </div> |  | ||||||
|             </template> |  | ||||||
|           </el-table-column> |  | ||||||
|           <el-table-column slot="options" label="操作" fixed="right" align="center"> |  | ||||||
|             <template slot-scope="{row}"> |  | ||||||
|               <div class="table-options"> |  | ||||||
|                 <el-button type="text" @click="openDetail(row.id)" v-if="$permissions('admin_sysdictionary_edit')">编辑</el-button> |  | ||||||
|                 <el-button type="text" @click="handleDelete(row.id)" v-if="$permissions('admin_sysdictionary_del')">删除</el-button> |  | ||||||
|               </div> |  | ||||||
|             </template> |  | ||||||
|           </el-table-column> |  | ||||||
|         </ai-table> |  | ||||||
|       </template> |  | ||||||
|     </ai-list> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .dictList { |  | ||||||
|   height: 100%; |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -40,7 +40,7 @@ | |||||||
|                 <div v-if="node.isLeaf" class="opBtn del" v-text="`删除`" @click="handleDelete(data)"/> |                 <div v-if="node.isLeaf" class="opBtn del" v-text="`删除`" @click="handleDelete(data)"/> | ||||||
|                 <div v-if="permissions('guide_page_config')&&data.component&&data.type==1" class="opBtn" v-text="`引导页`" |                 <div v-if="permissions('guide_page_config')&&data.component&&data.type==1" class="opBtn" v-text="`引导页`" | ||||||
|                      @click="$router.push({hash:'#intro',query:{id:data.id}})"/> |                      @click="$router.push({hash:'#intro',query:{id:data.id}})"/> | ||||||
|                 <div v-if="!data.component" class="opBtn" v-text="`添加下级`" @click="addMenu(data)"/> |                 <div v-if="data.type<2" class="opBtn" v-text="`添加下级`" @click="addMenu(data)"/> | ||||||
|                 <div class="opBtn" v-text="`编辑`" @click="handleEdit(data)"/> |                 <div class="opBtn" v-text="`编辑`" @click="handleEdit(data)"/> | ||||||
|               </el-row> |               </el-row> | ||||||
|             </el-row> |             </el-row> | ||||||
| @@ -54,16 +54,29 @@ | |||||||
|         <el-form-item label="菜单名称" prop="name"> |         <el-form-item label="菜单名称" prop="name"> | ||||||
|           <el-input v-model="form.name" placeholder="请输入" clearable/> |           <el-input v-model="form.name" placeholder="请输入" clearable/> | ||||||
|         </el-form-item> |         </el-form-item> | ||||||
|  |         <el-form-item label="菜单类型" prop="type"> | ||||||
|  |           <ai-select v-model="form.type" clearable :selectList="dict.getDict('menuType')"/> | ||||||
|  |         </el-form-item> | ||||||
|  |         <template v-if="form.type==0"> | ||||||
|           <el-form-item label="菜单图标" prop="style"> |           <el-form-item label="菜单图标" prop="style"> | ||||||
|             <el-input v-model="form.style" placeholder="请输入" clearable/> |             <el-input v-model="form.style" placeholder="请输入" clearable/> | ||||||
|           </el-form-item> |           </el-form-item> | ||||||
|  |         </template> | ||||||
|  |         <template v-if="form.type==1"> | ||||||
|  |           <el-form-item label="菜单图标" prop="style"> | ||||||
|  |             <el-input v-model="form.style" placeholder="请输入" clearable/> | ||||||
|  |           </el-form-item> | ||||||
|  |           <el-form-item label="路由名" prop="route"> | ||||||
|  |             <span v-text="form.route||'提交保存后会自动生成'"/> | ||||||
|  |           </el-form-item> | ||||||
|           <el-form-item label="菜单应用" prop="component"> |           <el-form-item label="菜单应用" prop="component"> | ||||||
|             <el-input v-model="form.component" placeholder="请输入" clearable/> |             <el-input v-model="form.component" placeholder="请输入" clearable/> | ||||||
|           </el-form-item> |           </el-form-item> | ||||||
|           <el-form-item label="路径(path)" prop="path"> |           <el-form-item label="路径(path)" prop="path"> | ||||||
|             <el-input v-model="form.path" placeholder="请输入" clearable/> |             <el-input v-model="form.path" placeholder="请输入" clearable/> | ||||||
|           </el-form-item> |           </el-form-item> | ||||||
|         <template v-if="form.component"> |         </template> | ||||||
|  |         <template v-if="form.type==2"> | ||||||
|           <el-form-item label="权限码" prop="permission"> |           <el-form-item label="权限码" prop="permission"> | ||||||
|             <el-input v-model="form.permission" placeholder="请输入" clearable/> |             <el-input v-model="form.permission" placeholder="请输入" clearable/> | ||||||
|           </el-form-item> |           </el-form-item> | ||||||
| @@ -71,7 +84,7 @@ | |||||||
|         <el-form-item label="显示菜单" prop="status"> |         <el-form-item label="显示菜单" prop="status"> | ||||||
|           <ai-select v-model="form.status" clearable :selectList="dict.getDict('yesOrNo')"/> |           <ai-select v-model="form.status" clearable :selectList="dict.getDict('yesOrNo')"/> | ||||||
|         </el-form-item> |         </el-form-item> | ||||||
|         <el-form-item label="排序" prop="showIndex"> |         <el-form-item v-if="form.type<2" label="排序" prop="showIndex"> | ||||||
|           <el-input v-model="form.showIndex" placeholder="请输入" clearable/> |           <el-input v-model="form.showIndex" placeholder="请输入" clearable/> | ||||||
|         </el-form-item> |         </el-form-item> | ||||||
|       </el-form> |       </el-form> | ||||||
|   | |||||||
| @@ -1,66 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <div class="doc-circulation ailist-wrapper"> |  | ||||||
|     <keep-alive :include="['List']"> |  | ||||||
|       <component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component> |  | ||||||
|     </keep-alive> |  | ||||||
|   </div> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   import List from './components/List' |  | ||||||
|   import Add from './components/Add' |  | ||||||
|  |  | ||||||
|   export default { |  | ||||||
|     name: 'AppAddressBook', |  | ||||||
|     label: '通讯录管理', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data () { |  | ||||||
|       return { |  | ||||||
|         component: 'List', |  | ||||||
|         params: {}, |  | ||||||
|         include: [] |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     components: { |  | ||||||
|       Add, |  | ||||||
|       List |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     mounted () { |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       onChange (data) { |  | ||||||
|         if (data.type === 'Add') { |  | ||||||
|           this.component = 'Add' |  | ||||||
|           this.params = data.params |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (data.type === 'list') { |  | ||||||
|           this.component = 'List' |  | ||||||
|           this.params = data.params |  | ||||||
|  |  | ||||||
|           this.$nextTick(() => { |  | ||||||
|             if (data.isRefresh) { |  | ||||||
|               this.$refs.component.getList() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss"> |  | ||||||
|   .doc-circulation { |  | ||||||
|     height: 100%; |  | ||||||
|     background: #F3F6F9; |  | ||||||
|     overflow: auto; |  | ||||||
|   } |  | ||||||
| </style> |  | ||||||
| @@ -1,203 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <ai-detail> |  | ||||||
|     <template slot="title"> |  | ||||||
|       <ai-title :title="id ? '编辑成员' : '添加成员'" isShowBack isShowBottomBorder @onBackClick="cancel(false)"> |  | ||||||
|       </ai-title> |  | ||||||
|     </template> |  | ||||||
|     <template slot="content">   |  | ||||||
|       <el-form ref="form" :model="form" label-width="110px" label-position="right"> |  | ||||||
|       <ai-card title="个人信息"> |  | ||||||
|         <template #content> |  | ||||||
|           <div class="ai-form"> |  | ||||||
|             <el-form-item label="姓名" prop="name" :rules="[{ required: true, message: '请输入姓名', trigger: 'blur' }]"> |  | ||||||
|               <el-input size="small" placeholder="请输入姓名" show-word-limit v-model="form.name" :maxlength="10"></el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="账号" prop="id" :rules="[{ required: true, message: '请输入账号', trigger: 'blur' }]"> |  | ||||||
|               <el-input size="small" :disabled="!!id" show-word-limit :maxlength="30" placeholder="成员唯一标识,设定以后不支持修改" v-model="form.id"></el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="手机号" prop="mobile" :rules="[{ required: true, validator: validatorPhone, trigger: 'blur' }]"> |  | ||||||
|               <el-input size="small" placeholder="请输入手机号" show-word-limit :maxlength="11" v-model="form.mobile"></el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="性别" prop="gender"> |  | ||||||
|               <el-radio-group v-model="form.gender"> |  | ||||||
|                 <el-radio label="1">男</el-radio> |  | ||||||
|                 <el-radio label="2">女</el-radio> |  | ||||||
|               </el-radio-group> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="座机" prop="telephone"> |  | ||||||
|               <el-input size="small" placeholder="请输入座机" v-model="form.telephone"></el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="邮箱" prop="email"> |  | ||||||
|               <el-input size="small" placeholder="请输入邮箱" v-model="form.email"></el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="地址" style="width: 100%;" prop="address"> |  | ||||||
|               <el-input size="small" style="width: 100%;" show-word-limit :maxlength="30" placeholder="请输入地址" v-model="form.address"></el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|           </div> |  | ||||||
|         </template> |  | ||||||
|       </ai-card> |  | ||||||
|       <ai-card title="组织信息"> |  | ||||||
|         <template #content> |  | ||||||
|           <el-form-item label="部门" prop="departmentName" style="width: 100%;" :rules="[{ required: true, message: '请选择部门', trigger: 'change' }]"> |  | ||||||
|             <el-input size="small" placeholder="请选择..." disabled v-model="form.departmentName"> |  | ||||||
|               <ai-wechat-selecter slot="append" isStrictly :instance="instance" @change="onChange" v-model="department" isChooseUnit> |  | ||||||
|                 <el-button type="info">选择</el-button> |  | ||||||
|               </ai-wechat-selecter> |  | ||||||
|             </el-input> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="标签" style="width: 100%;" prop="tags"> |  | ||||||
|             <el-select size="small" v-model="form.tagIds" multiple placeholder="请选择标签"> |  | ||||||
|               <el-option |  | ||||||
|                 v-for="item in tagsList" |  | ||||||
|                 :key="item.id" |  | ||||||
|                 :label="item.tagname" |  | ||||||
|                 :value="item.id"> |  | ||||||
|               </el-option> |  | ||||||
|             </el-select> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="职务" prop="position"> |  | ||||||
|             <el-input size="small" placeholder="请输入职务" v-model="form.position"></el-input> |  | ||||||
|           </el-form-item> |  | ||||||
|         </template> |  | ||||||
|       </ai-card> |  | ||||||
|       </el-form> |  | ||||||
|     </template> |  | ||||||
|     <template #footer> |  | ||||||
|       <el-button @click="cancel">取消</el-button> |  | ||||||
|       <el-button type="primary" @click="confirm">提交</el-button> |  | ||||||
|     </template> |  | ||||||
|   </ai-detail> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   export default { |  | ||||||
|     name: 'Add', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object, |  | ||||||
|       params: Object |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data () { |  | ||||||
|       const validatorPhone = function (rule, value, callback) { |  | ||||||
|         if (value === '') { |  | ||||||
|           callback(new Error('请输入手机号')) |  | ||||||
|         } else if (!/^1\d{10}$/.test(value)) { |  | ||||||
|           callback(new Error('手机号格式错误')) |  | ||||||
|         } else { |  | ||||||
|           callback() |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|       return { |  | ||||||
|         info: {}, |  | ||||||
|         department: [], |  | ||||||
|         validatorPhone: validatorPhone, |  | ||||||
|         form: { |  | ||||||
|           position: '', |  | ||||||
|           name: '', |  | ||||||
|           email: '', |  | ||||||
|           telephone: '', |  | ||||||
|           gender: '', |  | ||||||
|           mobile: '', |  | ||||||
|           departmentName: '', |  | ||||||
|           departmentIds: [], |  | ||||||
|           tagIds: [], |  | ||||||
|           id: '' |  | ||||||
|         }, |  | ||||||
|         id: '', |  | ||||||
|         tagsList: [] |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     created () { |  | ||||||
|       this.getTags() |  | ||||||
|  |  | ||||||
|       if (this.params && this.params.departmentId && !this.params.id) { |  | ||||||
|         this.department = [{ |  | ||||||
|           id: String(this.params.departmentId), |  | ||||||
|           name: this.params.departmentName |  | ||||||
|         }] |  | ||||||
|         this.form.departmentIds = [this.params.departmentId] |  | ||||||
|         this.form.departmentName = this.params.departmentName |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       if (this.params && this.params.id) { |  | ||||||
|         this.id = this.params.id |  | ||||||
|         this.getInfo(this.params.id) |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       getInfo (id) { |  | ||||||
|         this.instance.post(`/app/wxcp/wxuser/queryDetailById?id=${id}`).then(res => { |  | ||||||
|           if (res.code === 0) { |  | ||||||
|             const departmentNames = res.data.departmentNames.split(',') |  | ||||||
|             this.department = res.data.departmentIdsStr.split(',').map((item, index) => { |  | ||||||
|               return { |  | ||||||
|                 name: departmentNames[index], |  | ||||||
|                 id: item |  | ||||||
|               } |  | ||||||
|             }) |  | ||||||
|             this.form = { |  | ||||||
|               ...res.data, |  | ||||||
|               departmentName: res.data.departmentNames, |  | ||||||
|               tagIds: res.data.tags.map(v => v.id), |  | ||||||
|               departmentIds: res.data.departmentIdsStr.split(',') |  | ||||||
|             } |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       onChange (e) { |  | ||||||
|         if (e.length) { |  | ||||||
|           this.form.departmentIds = e.map(v => v.id) |  | ||||||
|           this.form.departmentName = e.map(v => v.name).join(',') |  | ||||||
|         } else { |  | ||||||
|           this.form.departmentIds = '' |  | ||||||
|           this.form.departmentName = '' |  | ||||||
|         } |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       getTags () { |  | ||||||
|         this.instance.post(`/app/wxcp/wxtag/listAll`).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.tagsList = res.data |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       onClose () { |  | ||||||
|         this.form.explain = '' |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       confirm () { |  | ||||||
|         this.$refs.form.validate((valid) => { |  | ||||||
|           if (valid) { |  | ||||||
|             const api = this.id ? '/app/wxcp/wxuser/update' : '/app/wxcp/wxuser/add' |  | ||||||
|             this.instance.post(api, { |  | ||||||
|               ...this.form |  | ||||||
|             }).then(res => { |  | ||||||
|               if (res.code == 0) { |  | ||||||
|                 this.$message.success('提交成功') |  | ||||||
|                 setTimeout(() => { |  | ||||||
|                   this.cancel(true) |  | ||||||
|                 }, 600) |  | ||||||
|               } |  | ||||||
|             }) |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       cancel (isRefresh) { |  | ||||||
|         this.$emit('change', { |  | ||||||
|           type: 'list', |  | ||||||
|           isRefresh: !!isRefresh |  | ||||||
|         }) |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| </style> |  | ||||||
| @@ -1,995 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <ai-list class="addressBook"> |  | ||||||
|     <template slot="title"> |  | ||||||
|       <ai-title title="内部通讯录" isShowBottomBorder></ai-title> |  | ||||||
|     </template> |  | ||||||
|     <template #left> |  | ||||||
|       <div class="addressBook-left"> |  | ||||||
|         <div class="addressBook-left__title"> |  | ||||||
|           <h2 @click="tabIndex = 0, search.current = 1, getList()" :class="[tabIndex === 0 ? 'tab-active' : '']"> |  | ||||||
|             组织架构</h2> |  | ||||||
|           <h2 @click="tabIndex = 1, search.current = 1, getList()" :class="[tabIndex === 1 ? 'tab-active' : '']">标签</h2> |  | ||||||
|         </div> |  | ||||||
|         <div class="addressBook-left__list--title" v-if="tabIndex === 0"> |  | ||||||
|           <el-input |  | ||||||
|               size="mini" |  | ||||||
|               placeholder="请输入部门名称" |  | ||||||
|               v-model="unitName" |  | ||||||
|               clearable |  | ||||||
|               suffix-icon="iconfont iconSearch"> |  | ||||||
|           </el-input> |  | ||||||
|         </div> |  | ||||||
|         <div class="addressBook-left__list--title" v-if="tabIndex === 1"> |  | ||||||
|           <el-button size="mini" icon="iconfont iconAdd" @click="isShowTags = true">添加标签</el-button> |  | ||||||
|           <el-input |  | ||||||
|               class="addressBook-left__list--search" |  | ||||||
|               size="mini" |  | ||||||
|               clearable |  | ||||||
|               style="width: 154px;" |  | ||||||
|               placeholder="请输入标签名称" |  | ||||||
|               v-model="tagName" |  | ||||||
|               suffix-icon="iconfont iconSearch"> |  | ||||||
|           </el-input> |  | ||||||
|         </div> |  | ||||||
|         <div class="addressBook-left__list--wrapper"> |  | ||||||
|           <div class="addressBook-left__list" v-show="tabIndex === 0"> |  | ||||||
|             <el-tree |  | ||||||
|               :filter-node-method="filterNode" |  | ||||||
|               ref="tree" |  | ||||||
|               :props="defaultProps" |  | ||||||
|               node-key="id" |  | ||||||
|               :data="unitList" |  | ||||||
|               highlight-current |  | ||||||
|               @node-contextmenu="nodeContextmenu" |  | ||||||
|               :current-node-key="search.departmentId" |  | ||||||
|               :default-expanded-keys="defaultExpanded" |  | ||||||
|               :default-checked-keys="defaultChecked" |  | ||||||
|               @current-change="onTreeChange"> |  | ||||||
|             </el-tree> |  | ||||||
|             <ul |  | ||||||
|                 v-if="isShowMenu" |  | ||||||
|                 class="el-dropdown-menu el-popper" |  | ||||||
|                 :style="{top: menuInfo.y + 'px', left: menuInfo.x + 'px', position: 'fixed', zIndex: 2023}" |  | ||||||
|                 x-placement="top-end"> |  | ||||||
|               <li class="el-dropdown-menu__item" @click="handleTreeCommand('add', menuInfo.node)">添加子部门</li> |  | ||||||
|               <li class="el-dropdown-menu__item" @click="handleTreeCommand('edit', menuInfo.node)">修改名称</li> |  | ||||||
|               <li class="el-dropdown-menu__item" @click="handleTreeCommand('remove', menuInfo.node)">删除</li> |  | ||||||
|               <li class="el-dropdown-menu__item" :class="[!menuInfo.node.i ? 'is-disabled' : '']" |  | ||||||
|                   @click="handleTreeCommand('top', menuInfo.node)">上移 |  | ||||||
|               </li> |  | ||||||
|               <li |  | ||||||
|                   class="el-dropdown-menu__item" |  | ||||||
|                   :class="[(menuInfo.node.i === menuInfo.node.len - 1) || (!menuInfo.node.i && menuInfo.node.i !== 0) ? 'is-disabled' : '']" |  | ||||||
|                   @click="handleTreeCommand('bottom', menuInfo.node)">下移 |  | ||||||
|               </li> |  | ||||||
|             </ul> |  | ||||||
|           </div> |  | ||||||
|           <div class="addressBook-left__list" v-show="tabIndex === 1"> |  | ||||||
|             <div class="addressBook-left__tags"> |  | ||||||
|               <div |  | ||||||
|                   @click="changeTag(index)" |  | ||||||
|                   class="addressBook-left__tags--item" |  | ||||||
|                   :class="[currIndex === index ? 'addressBook-left__tags--item-active' : '']" |  | ||||||
|                   v-for="(item, index) in tagsList" :key="index"> |  | ||||||
|                 <span>{{ item.tagname }}</span> |  | ||||||
|                 <el-dropdown @command="e => handleCommand(e, item)"> |  | ||||||
|                   <i class="iconfont iconmore"></i> |  | ||||||
|                   <el-dropdown-menu slot="dropdown"> |  | ||||||
|                     <el-dropdown-item command="edit">编辑</el-dropdown-item> |  | ||||||
|                     <el-dropdown-item command="remove">删除</el-dropdown-item> |  | ||||||
|                   </el-dropdown-menu> |  | ||||||
|                 </el-dropdown> |  | ||||||
|               </div> |  | ||||||
|             </div> |  | ||||||
|           </div> |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|     </template> |  | ||||||
|     <template slot="content"> |  | ||||||
|       <ai-search-bar class="search-bar"> |  | ||||||
|         <template #left> |  | ||||||
|           <el-button size="small" type="primary" icon="iconfont iconAdd" v-if="tabIndex === 0" @click="toAdd('')">添加成员 |  | ||||||
|           </el-button> |  | ||||||
|           <ai-import :instance="instance" :dict="dict" v-if="tabIndex === 0" type="wxcp/wxuser" name="内部通讯录" |  | ||||||
|                      :importParams="{departmentId:search.departmentId}" @success="getList"/> |  | ||||||
|           <el-button size="small" icon="iconfont iconUpdate_Files" v-if="tabIndex === 0" :loading="btnLoading" @click="syncMembers">同步部门</el-button> |  | ||||||
|           <el-button size="small" icon="iconfont iconUpdate_Files" v-if="tabIndex === 0" :loading="btnLoading" @click="syncUser">同步成员</el-button> |  | ||||||
|           <ai-wechat-selecter refs="addTags" :instance="instance" v-model="users" @change="onChooseUser" |  | ||||||
|                               :disabled="currIndex < 0" v-if="tabIndex === 1"> |  | ||||||
|             <el-button size="small" :disabled="currIndex < 0" type="primary" icon="iconfont iconAdd">添加成员</el-button> |  | ||||||
|           </ai-wechat-selecter> |  | ||||||
|         </template> |  | ||||||
|         <template slot="right"> |  | ||||||
|           <el-input |  | ||||||
|               v-model="search.name" |  | ||||||
|               size="small" |  | ||||||
|               v-throttle="() => {search.current = 1, getList()}" |  | ||||||
|               placeholder="请输入成员姓名、手机号或标签名称" |  | ||||||
|               clearable |  | ||||||
|               @clear="search.current = 1, search.name = '', getList()" |  | ||||||
|               suffix-icon="iconfont iconSearch"> |  | ||||||
|           </el-input> |  | ||||||
|         </template> |  | ||||||
|       </ai-search-bar> |  | ||||||
|       <ai-table |  | ||||||
|           :tableData="tableData" |  | ||||||
|           :col-configs="colConfigs" |  | ||||||
|           :total="total" |  | ||||||
|           v-loading="loading" |  | ||||||
|           style="margin-top: 6px;" |  | ||||||
|           :current.sync="search.current" |  | ||||||
|           :size.sync="search.size" |  | ||||||
|           @handleSelectionChange="handleSelectionChange" |  | ||||||
|           @getList="getList"> |  | ||||||
|         <el-table-column slot="avatar" label="" align="right" width="100px"> |  | ||||||
|           <template slot-scope="{ row }"> |  | ||||||
|             <img class="table-avatar" :src="row.avatar || 'https://cdn.cunwuyun.cn/dvcp/h5/defaultAvatar.png'"> |  | ||||||
|           </template> |  | ||||||
|         </el-table-column> |  | ||||||
|         <el-table-column slot="tags" label="标签" align="left"> |  | ||||||
|           <template slot-scope="{ row }"> |  | ||||||
|             <div class="table-tags" v-if="row.tagNames"> |  | ||||||
|               <el-tag type="info" v-for="(item, index) in row.tagNames.split('、')" size="small" :key="index">{{ |  | ||||||
|                   item |  | ||||||
|                 }} |  | ||||||
|               </el-tag> |  | ||||||
|             </div> |  | ||||||
|           </template> |  | ||||||
|         </el-table-column> |  | ||||||
|         <el-table-column slot="options" width="140px" fixed="right" label="操作" align="center"> |  | ||||||
|           <template slot-scope="{ row }"> |  | ||||||
|             <div class="table-options"> |  | ||||||
|               <el-button type="text" @click="toAdd(row.id)" v-show="tabIndex === 0">编辑</el-button> |  | ||||||
|               <el-button type="text" @click="remove(row.id)" v-show="tabIndex === 0">删除</el-button> |  | ||||||
|               <el-button type="text" @click="removeTags(row.id)" v-show="tabIndex === 1">移除</el-button> |  | ||||||
|             </div> |  | ||||||
|           </template> |  | ||||||
|         </el-table-column> |  | ||||||
|         <div slot="paginationBtns" class="addressBook-table__btns"> |  | ||||||
|           <span style="margin-right: 8px;" @click="removeAll">{{ tabIndex === 0 ? '批量删除' : '批量移除' }}</span> |  | ||||||
|           <ai-wechat-selecter :instance="instance" v-model="department" isChooseUnit @change="onDepartment" |  | ||||||
|                               v-if="tabIndex === 0"> |  | ||||||
|             <span>批量导出</span> |  | ||||||
|           </ai-wechat-selecter> |  | ||||||
|         </div> |  | ||||||
|       </ai-table> |  | ||||||
|       <ai-dialog |  | ||||||
|           :visible.sync="isShowTags" |  | ||||||
|           width="590px" |  | ||||||
|           :title="tagId ? '编辑标签' : '添加标签'" |  | ||||||
|           @close="onClose" |  | ||||||
|           @onConfirm="onFormConfirm"> |  | ||||||
|         <el-form ref="tagForm" :model="tagForm" label-width="110px" label-position="right"> |  | ||||||
|           <el-form-item label="标签名称" prop="tagname" :rules="[{ required: true, message: '请输入标签名称', trigger: 'blur' }]"> |  | ||||||
|             <el-input size="small" placeholder="请输入标签名称" show-word-limit :maxlength="10" v-model="tagForm.tagname"></el-input> |  | ||||||
|           </el-form-item> |  | ||||||
|         </el-form> |  | ||||||
|       </ai-dialog> |  | ||||||
|       <ai-dialog |  | ||||||
|           :visible.sync="isShowDepart" |  | ||||||
|           width="590px" |  | ||||||
|           :title="departId ? '修改名称' : '添加部门'" |  | ||||||
|           @close="onClose" |  | ||||||
|           @onConfirm="onDepartConfirm"> |  | ||||||
|         <el-form ref="departForm" :model="departForm" label-width="110px" label-position="right"> |  | ||||||
|           <el-form-item label="部门名称" prop="name" :rules="[{ required: true, message: '请输入部门名称', trigger: 'blur' }]"> |  | ||||||
|             <el-input size="small" placeholder="请输入部门名称" show-word-limit :maxlength="30" v-model="departForm.name"></el-input> |  | ||||||
|           </el-form-item> |  | ||||||
|         </el-form> |  | ||||||
|       </ai-dialog> |  | ||||||
|     </template> |  | ||||||
|   </ai-list> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| import {mapState} from 'vuex' |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: 'List', |  | ||||||
|  |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object |  | ||||||
|   }, |  | ||||||
|  |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       users: [], |  | ||||||
|       isShowMenu: false, |  | ||||||
|       department: [], |  | ||||||
|       btnLoading: false, |  | ||||||
|       menuInfo: { |  | ||||||
|         x: '', |  | ||||||
|         y: '', |  | ||||||
|         node: {} |  | ||||||
|       }, |  | ||||||
|       search: { |  | ||||||
|         current: 1, |  | ||||||
|         size: 10, |  | ||||||
|         title: '', |  | ||||||
|         tagname: '', |  | ||||||
|         name: '', |  | ||||||
|         tagIds: '', |  | ||||||
|         departmentId: '' |  | ||||||
|       }, |  | ||||||
|       tagForm: { |  | ||||||
|         tagname: '' |  | ||||||
|       }, |  | ||||||
|       isShowDepart: false, |  | ||||||
|       departForm: { |  | ||||||
|         name: '' |  | ||||||
|       }, |  | ||||||
|       loading: false, |  | ||||||
|       isShowTags: false, |  | ||||||
|       defaultChecked: [], |  | ||||||
|       defaultExpanded: [], |  | ||||||
|       tabIndex: 0, |  | ||||||
|       currIndex: -1, |  | ||||||
|       areaList: [], |  | ||||||
|       total: 0, |  | ||||||
|       colConfigs: [ |  | ||||||
|         {type: 'selection', label: ''}, |  | ||||||
|         {slot: 'avatar', label: ''}, |  | ||||||
|         {prop: 'name', label: '姓名'}, |  | ||||||
|         {prop: 'position', label: '职务'}, |  | ||||||
|         {prop: 'departmentNames', label: '部门'}, |  | ||||||
|         {prop: 'mobile', label: '手机号'}, |  | ||||||
|         {slot: 'tags', label: '标签'}, |  | ||||||
|         {prop: 'status', label: '账号状态', align: 'center', format: v => v == 1 ? '已激活' : '未激活'} |  | ||||||
|       ], |  | ||||||
|       defaultProps: { |  | ||||||
|         children: 'children', |  | ||||||
|         label: 'name' |  | ||||||
|       }, |  | ||||||
|       unitName: '', |  | ||||||
|       rootId: '', |  | ||||||
|       unitList: [], |  | ||||||
|       tagsList: [], |  | ||||||
|       tagName: '', |  | ||||||
|       sourceTagList: [], |  | ||||||
|       tableData: [], |  | ||||||
|       tagId: '', |  | ||||||
|       departmentName: '', |  | ||||||
|       departId: '', |  | ||||||
|       ids: '' |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|  |  | ||||||
|   computed: { |  | ||||||
|     ...mapState(['user']) |  | ||||||
|   }, |  | ||||||
|  |  | ||||||
|   watch: { |  | ||||||
|     unitName(val) { |  | ||||||
|       this.$refs.tree.filter(val) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     tagName(val) { |  | ||||||
|       if (!val) { |  | ||||||
|         this.tagsList = this.sourceTagList |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       this.tagsList = this.sourceTagList.filter(v => v.tagname.indexOf(val) > -1) |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|  |  | ||||||
|   mounted() { |  | ||||||
|     this.getTree() |  | ||||||
|     this.getList() |  | ||||||
|     this.getTags() |  | ||||||
|     document.querySelector('html').addEventListener('click', this.bindEvent) |  | ||||||
|  |  | ||||||
|     this.$nextTick(() => { |  | ||||||
|     }) |  | ||||||
|   }, |  | ||||||
|  |  | ||||||
|   methods: { |  | ||||||
|     changeTag(index) { |  | ||||||
|       this.currIndex = index |  | ||||||
|       this.search.current = 1 |  | ||||||
|  |  | ||||||
|       this.$nextTick(() => { |  | ||||||
|         this.getList() |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     bindEvent() { |  | ||||||
|       this.isShowMenu = false |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     nodeContextmenu(e, node) { |  | ||||||
|       this.isShowMenu = true |  | ||||||
|       let y = e.y + 6 |  | ||||||
|       if (y + 202 > document.body.clientHeight) { |  | ||||||
|         y = y - 202 |  | ||||||
|       } |  | ||||||
|       this.menuInfo = { |  | ||||||
|         x: e.x + 16, y, |  | ||||||
|         node |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     removeTags(id) { |  | ||||||
|       if (this.currIndex < 0) { |  | ||||||
|         return this.$message.error('请选择标签') |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       this.$confirm('确定移除该成员?').then(() => { |  | ||||||
|         this.instance.post(`/app/wxcp/wxtag/removeTag?userIds=${id}&tagId=${this.tagsList[this.currIndex].id}`).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.$message.success('移除成功!') |  | ||||||
|             this.search.current = 1 |  | ||||||
|  |  | ||||||
|             this.getList() |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     onDepartment(e) { |  | ||||||
|       if (!e.length) { |  | ||||||
|         return this.$message.error('请选择部门') |  | ||||||
|       } |  | ||||||
|       const ids = e.map(v => v.id).join(',') |  | ||||||
|  |  | ||||||
|       this.department = [] |  | ||||||
|       this.instance.post(`/app/wxcp/wxuser/export?departmentId=${ids}`, null, { |  | ||||||
|         responseType: 'blob' |  | ||||||
|       }).then(res => { |  | ||||||
|         if (res?.type == "application/json") { |  | ||||||
|           let reader = new FileReader() |  | ||||||
|           reader.readAsText(res, "utf-8") |  | ||||||
|           reader.onload = e => { |  | ||||||
|             if (e.target.readyState === 2) { |  | ||||||
|               let ret = JSON.parse(e.target.result) |  | ||||||
|               if (ret?.code == 0) { |  | ||||||
|                 this.$message.success(ret.msg) |  | ||||||
|               } else this.$message.error(ret.msg) |  | ||||||
|             } |  | ||||||
|           } |  | ||||||
|         } else { |  | ||||||
|           const link = document.createElement('a') |  | ||||||
|           let blob = new Blob([res], {type: res.type}) |  | ||||||
|           link.style.display = 'none' |  | ||||||
|           link.href = URL.createObjectURL(blob) |  | ||||||
|           link.setAttribute('download', `${e[0].name}.xls`) |  | ||||||
|           document.body.appendChild(link) |  | ||||||
|           link.click() |  | ||||||
|           document.body.removeChild(link) |  | ||||||
|           this.$message.success('导出成功!') |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     onChooseUser(e) { |  | ||||||
|       if (!e.length) { |  | ||||||
|         return this.$message.error('请选择成员') |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       this.instance.post(`/app/wxcp/wxtag/markTag`, null, { |  | ||||||
|         params: { |  | ||||||
|           tagId: this.tagsList[this.currIndex].id, |  | ||||||
|           userIds: e.map(v => v.id).join(',') |  | ||||||
|         } |  | ||||||
|       }).then(res => { |  | ||||||
|         if (res.code == 0) { |  | ||||||
|           this.getList() |  | ||||||
|           this.users = [] |  | ||||||
|           this.search.current = 1 |  | ||||||
|           this.$refs.addTags.reset() |  | ||||||
|         } else { |  | ||||||
|           this.users = [] |  | ||||||
|         } |  | ||||||
|       }).catch(() => { |  | ||||||
|         this.users = [] |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     handleTreeCommand(e, item) { |  | ||||||
|       this.isShowMenu = false |  | ||||||
|  |  | ||||||
|       if (e === 'add') { |  | ||||||
|         this.departForm.id = '' |  | ||||||
|         this.departForm.parentid = item.id |  | ||||||
|         this.departId = '' |  | ||||||
|         this.isShowDepart = true |  | ||||||
|       } else if (e === 'edit') { |  | ||||||
|         this.departForm = { |  | ||||||
|           ...item |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this.departId = item.id |  | ||||||
|         this.isShowDepart = true |  | ||||||
|       } else if (e === 'top') { |  | ||||||
|         if (!item.i) { |  | ||||||
|           return false |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this.moveDepart(item.id, 0) |  | ||||||
|       } else if (e === 'bottom') { |  | ||||||
|         if ((item.i === item.len - 1) || (!item.i && item.i !== 0)) { |  | ||||||
|           return false |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this.moveDepart(item.id, 1) |  | ||||||
|       } else if (e === 'remove') { |  | ||||||
|         this.removeDepart(item.id, item.parentid) |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     removeDepart(id, parentid) { |  | ||||||
|       this.$confirm('确定删除该数据?').then(() => { |  | ||||||
|         this.instance.post(`/app/wxcp/wxdepartment/delete?id=${id}`).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.defaultChecked = [parentid] |  | ||||||
|             this.$message.success('删除成功!') |  | ||||||
|             this.getTree() |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     moveDepart(id, type) { |  | ||||||
|       this.instance.post(`/app/wxcp/wxdepartment/move?id=${id}&type=${type}`).then(res => { |  | ||||||
|         if (res.code == 0) { |  | ||||||
|           this.defaultChecked = [id] |  | ||||||
|           this.getTree() |  | ||||||
|           this.$message.success(type === 0 ? '上移成功' : '下移成功') |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     onDepartConfirm() { |  | ||||||
|       this.$refs.departForm.validate((valid) => { |  | ||||||
|         if (valid) { |  | ||||||
|           this.instance.post(`/app/wxcp/wxdepartment/addOrUpdate`, { |  | ||||||
|             ...this.departForm, |  | ||||||
|             departId: this.departId |  | ||||||
|           }).then(res => { |  | ||||||
|             if (res.code == 0) { |  | ||||||
|               this.defaultChecked = [this.departForm.parentid] |  | ||||||
|               this.isShowDepart = false |  | ||||||
|               this.getTree() |  | ||||||
|               this.$message.success(this.departId ? '编辑成功' : '新增成功') |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     onFormConfirm() { |  | ||||||
|       this.$refs.tagForm.validate((valid) => { |  | ||||||
|         if (valid) { |  | ||||||
|           this.instance.post(`/app/wxcp/wxtag/addOrUpdate`, { |  | ||||||
|             ...this.tagForm |  | ||||||
|           }).then(res => { |  | ||||||
|             if (res.code == 0) { |  | ||||||
|               this.isShowTags = false |  | ||||||
|               this.getTags() |  | ||||||
|               this.$message.success(this.tagId ? '编辑成功' : '新增成功') |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     handleCommand(e, item) { |  | ||||||
|       if (e === 'edit') { |  | ||||||
|         this.tagId = item.id |  | ||||||
|         this.tagForm = { |  | ||||||
|           ...item |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this.isShowTags = true |  | ||||||
|       } else { |  | ||||||
|         this.$confirm('确定删除该数据?').then(() => { |  | ||||||
|           this.instance.post(`/app/wxcp/wxtag/delete?id=${item.id}`).then(res => { |  | ||||||
|             if (res.code == 0) { |  | ||||||
|               this.$message.success('删除成功!') |  | ||||||
|               this.getTags() |  | ||||||
|               this.getList() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         }) |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     onClose() { |  | ||||||
|       this.tagId = '' |  | ||||||
|       this.tagForm.tagname = '' |  | ||||||
|       this.departForm.name = '' |  | ||||||
|       this.departId = '' |  | ||||||
|       this.departForm.nameEn = '' |  | ||||||
|       this.departForm.parentid = '' |  | ||||||
|       this.departForm.showIndex = '' |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     syncMembers() { |  | ||||||
|       this.btnLoading = true |  | ||||||
|  |  | ||||||
|       this.instance.post(`/app/wxcp/wxdepartment/syncDepart`).then(res => { |  | ||||||
|         if (res.code == 0) { |  | ||||||
|           this.$message.success('同步成功') |  | ||||||
|           this.getList() |  | ||||||
|           this.getTree() |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this.btnLoading = false |  | ||||||
|       }).catch(() => { |  | ||||||
|         this.btnLoading = false |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     syncUser() { |  | ||||||
|       let departId = this.search.departmentId; |  | ||||||
|       if (!departId) departId = 1; |  | ||||||
|       this.btnLoading = true |  | ||||||
|  |  | ||||||
|       this.instance.post(`/app/wxcp/wxdepartment/syncUser?departmentId=${departId}`, null, { |  | ||||||
|         timeout: 1000000 |  | ||||||
|       }).then(res => { |  | ||||||
|         if (res.code == 0) { |  | ||||||
|           this.$message.success('同步成功') |  | ||||||
|           this.getList() |  | ||||||
|           this.getTree() |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this.btnLoading = false |  | ||||||
|       }).catch(() => { |  | ||||||
|         this.btnLoading = false |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     getTags() { |  | ||||||
|       this.instance.post(`/app/wxcp/wxtag/listAll`).then(res => { |  | ||||||
|         if (res.code == 0) { |  | ||||||
|           this.sourceTagList = res.data.length ? JSON.parse(JSON.stringify(res.data)) : [] |  | ||||||
|           this.tagsList = res.data |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     onSwitchChange(id) { |  | ||||||
|       this.instance.post(`/app/wxcp/wxuser/enable?id=${id}`).then(res => { |  | ||||||
|         if (res.code == 0) { |  | ||||||
|           this.getList() |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     onTreeChange(e) { |  | ||||||
|       this.departmentName = e.name |  | ||||||
|       this.search.departmentId = e.id || '' |  | ||||||
|       this.search.current = 1 |  | ||||||
|       this.isShowMenu = false |  | ||||||
|  |  | ||||||
|       this.$nextTick(() => { |  | ||||||
|         this.getList() |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     getList() { |  | ||||||
|       this.loading = true |  | ||||||
|       this.instance.post(`/app/wxcp/wxuser/list`, null, { |  | ||||||
|         params: { |  | ||||||
|           ...this.search, |  | ||||||
|           departmentId: this.tabIndex === 0 ? this.search.departmentId : '', |  | ||||||
|           tagIds: this.tabIndex === 1 ? (this.currIndex >= 0 ? this.tagsList[this.currIndex].id : '') : '', |  | ||||||
|           listType: this.tabIndex |  | ||||||
|         } |  | ||||||
|       }).then(res => { |  | ||||||
|         if (res.code == 0) { |  | ||||||
|           this.tableData = res.data.records |  | ||||||
|           this.total = res.data.total |  | ||||||
|  |  | ||||||
|           this.$nextTick(() => { |  | ||||||
|             this.loading = false |  | ||||||
|           }) |  | ||||||
|         } else { |  | ||||||
|           this.loading = false |  | ||||||
|         } |  | ||||||
|       }).catch(() => { |  | ||||||
|         this.loading = false |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     removeAll() { |  | ||||||
|       if (!this.ids) return |  | ||||||
|  |  | ||||||
|       if (this.tabIndex === 1) { |  | ||||||
|         this.removeTags(this.ids) |  | ||||||
|       } else { |  | ||||||
|         this.remove(this.ids) |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     handleSelectionChange(e) { |  | ||||||
|       this.ids = e.map(v => v.id).join(',') |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     filterNode(value, data) { |  | ||||||
|       if (!value) return true |  | ||||||
|       return data.name.indexOf(value) !== -1 |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     changeTab(id, index) { |  | ||||||
|       this.currIndex = index |  | ||||||
|       this.search.areaId = id |  | ||||||
|  |  | ||||||
|       this.$nextTick(() => { |  | ||||||
|         this.getList() |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     getTree() { |  | ||||||
|       this.instance.post(`/app/wxcp/wxdepartment/listAll?unitName=${this.unitName}`).then(res => { |  | ||||||
|         if (res.code === 0) { |  | ||||||
|           let parent = res.data.map(v => { |  | ||||||
|             v.label = v.name |  | ||||||
|             v.children = [] |  | ||||||
|  |  | ||||||
|             return v |  | ||||||
|           }).filter(e => !e.parentid)[0] |  | ||||||
|           this.defaultExpanded = [parent.id] |  | ||||||
|           this.defaultChecked = [parent.id] |  | ||||||
|           this.search.departmentId = parent.id |  | ||||||
|           this.departmentName = parent.name |  | ||||||
|           this.addChild(parent, res.data) |  | ||||||
|           this.unitList = [parent] |  | ||||||
|  |  | ||||||
|           this.$nextTick(() => { |  | ||||||
|             this.$refs.tree.setCurrentKey(parent.id) |  | ||||||
|           }) |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     addChild(parent, list) { |  | ||||||
|       for (let i = 0; i < list.length; i++) { |  | ||||||
|         if (list[i].parentid === parent.id) { |  | ||||||
|           list[i].i = parent.children.length |  | ||||||
|           parent.children.push(list[i]) |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       if (parent.children.length) { |  | ||||||
|         parent.children.forEach(v => { |  | ||||||
|           v.len = parent.children.length |  | ||||||
|         }) |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       if (list.length > 0) { |  | ||||||
|         parent['children'].map(v => this.addChild(v, list)) |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     formatList(list) { |  | ||||||
|       var arr = [] |  | ||||||
|       for (let item of list) { |  | ||||||
|         if (item.childrenUser && item.childrenUser.length) { |  | ||||||
|           delete item.childrenUser |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (item.childrenDept && item.childrenDept.length) { |  | ||||||
|           this.formatList(item.childrenDept) |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         arr.push(item) |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       return arr |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     remove(id) { |  | ||||||
|       this.$confirm('确定删除该数据?').then(() => { |  | ||||||
|         this.instance.post(`/app/wxcp/wxuser/delete?id=${id}`).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.$message.success('删除成功!') |  | ||||||
|             this.getList() |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     toAdd(id) { |  | ||||||
|       this.$emit('change', { |  | ||||||
|         type: 'Add', |  | ||||||
|         params: { |  | ||||||
|           id: id || '', |  | ||||||
|           departmentId: this.search.departmentId || '', |  | ||||||
|           departmentName: this.departmentName || '' |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
| .addressBook { |  | ||||||
|   .addressBook-table__btns { |  | ||||||
|     display: flex; |  | ||||||
|     align-items: center; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   .table-tags { |  | ||||||
|     .el-tag { |  | ||||||
|       margin-right: 8px; |  | ||||||
|       margin-bottom: 8px; |  | ||||||
|  |  | ||||||
|       &:last-child { |  | ||||||
|         margin-right: 0; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .import-wrapper { |  | ||||||
|     & > h2 { |  | ||||||
|       margin-bottom: 8px; |  | ||||||
|       font-size: 16px; |  | ||||||
|       color: #222222; |  | ||||||
|       font-weight: Bold; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .import-wrapper__tips { |  | ||||||
|       line-height: 1; |  | ||||||
|       margin-bottom: 24px; |  | ||||||
|  |  | ||||||
|       div { |  | ||||||
|         display: flex; |  | ||||||
|         margin-bottom: 8px; |  | ||||||
|         color: #222222; |  | ||||||
|         font-size: 14px; |  | ||||||
|  |  | ||||||
|         span { |  | ||||||
|           cursor: pointer; |  | ||||||
|           color: #2266FF; |  | ||||||
|  |  | ||||||
|           &:hover { |  | ||||||
|             opacity: 0.8; |  | ||||||
|             text-decoration: underline; |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .import-files { |  | ||||||
|       i { |  | ||||||
|         display: block; |  | ||||||
|         margin-top: 8px; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     i { |  | ||||||
|       color: #999999; |  | ||||||
|       font-size: 12px; |  | ||||||
|       font-style: normal; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .tree-container { |  | ||||||
|     position: relative; |  | ||||||
|     display: flex; |  | ||||||
|     align-items: center; |  | ||||||
|     justify-content: space-between; |  | ||||||
|     width: 100%; |  | ||||||
|     height: 100%; |  | ||||||
|  |  | ||||||
|     .tree-name { |  | ||||||
|       padding-right: 30px; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     i { |  | ||||||
|       position: absolute; |  | ||||||
|       top: 50%; |  | ||||||
|       right: 8px; |  | ||||||
|       transform: translateY(-50%); |  | ||||||
|       padding-right: 8px; |  | ||||||
|       font-weight: normal; |  | ||||||
|       color: #fff; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .el-tag { |  | ||||||
|     margin-right: 8px; |  | ||||||
|     border: 1px solid #D0D4DC; |  | ||||||
|     background: #F3F4F7; |  | ||||||
|     border-radius: 4px; |  | ||||||
|     font-size: 13px; |  | ||||||
|     color: #222222; |  | ||||||
|  |  | ||||||
|     &:last-child { |  | ||||||
|       margin-right: 0; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .table-avatar { |  | ||||||
|     width: 40px; |  | ||||||
|     height: 40px; |  | ||||||
|     margin-top: 3px; |  | ||||||
|     border-radius: 2px; |  | ||||||
|     border: 1px solid #CCCCCC; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .el-button--mini, .el-button--mini.is-round { |  | ||||||
|     height: 28px; |  | ||||||
|     line-height: 28px; |  | ||||||
|     padding: 0; |  | ||||||
|     font-size: 12px; |  | ||||||
|  |  | ||||||
|     :deep( span ){ |  | ||||||
|       margin-left: 0; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .addressBook-left__list--title { |  | ||||||
|     display: flex; |  | ||||||
|     align-items: center; |  | ||||||
|     margin: 8px 8px 0; |  | ||||||
|  |  | ||||||
|     .addressBook-left__list--search { |  | ||||||
|       flex: 1; |  | ||||||
|  |  | ||||||
|       :deep( input ){ |  | ||||||
|         width: 100%; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .el-button { |  | ||||||
|       width: 84px; |  | ||||||
|       flex-shrink: 1; |  | ||||||
|       margin-right: 8px; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .addressBook-left { |  | ||||||
|     width: 100%; |  | ||||||
|     height: auto; |  | ||||||
|     background: #FAFAFB; |  | ||||||
|  |  | ||||||
|     .addressBook-left__title { |  | ||||||
|       display: flex; |  | ||||||
|       align-items: center; |  | ||||||
|       width: 100%; |  | ||||||
|       height: 40px; |  | ||||||
|       background: #ffffff; |  | ||||||
|  |  | ||||||
|       h2 { |  | ||||||
|         flex: 1; |  | ||||||
|         height: 100%; |  | ||||||
|         line-height: 40px; |  | ||||||
|         color: #222; |  | ||||||
|         font-size: 14px; |  | ||||||
|         text-align: center; |  | ||||||
|         cursor: pointer; |  | ||||||
|         border-bottom: 2px solid transparent; |  | ||||||
|  |  | ||||||
|         &.tab-active { |  | ||||||
|           color: #2266FF; |  | ||||||
|           border-bottom: 2px solid #2266FF; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // ::-webkit-scrollbar { |  | ||||||
|     //   width: 1px; |  | ||||||
|     // } |  | ||||||
|  |  | ||||||
|     .addressBook-left__list--wrapper { |  | ||||||
|       height: calc(100% - 68px); |  | ||||||
|       padding: 8px; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .addressBook-left__list { |  | ||||||
|       width: 100%; |  | ||||||
|       height: 100%; |  | ||||||
|       overflow: auto; |  | ||||||
|  |  | ||||||
|       :deep( .el-tree ){ |  | ||||||
|         width: fit-content; |  | ||||||
|         min-width: 100%; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       :deep( .el-scrollbar__wrap ){ |  | ||||||
|         margin-bottom: 0 !important; |  | ||||||
|         overflow-x: hidden; |  | ||||||
|  |  | ||||||
|         .el-scrollbar__view { |  | ||||||
|           width: fit-content; |  | ||||||
|           min-width: 100%; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .addressBook-left__tags--item { |  | ||||||
|         display: flex; |  | ||||||
|         align-items: center; |  | ||||||
|         justify-content: space-between; |  | ||||||
|         height: 40px; |  | ||||||
|         padding: 0 8px 0 16px; |  | ||||||
|         cursor: pointer; |  | ||||||
|         color: #222222; |  | ||||||
|  |  | ||||||
|         &.addressBook-left__tags--item-active, &:hover { |  | ||||||
|           background: #E8EFFF; |  | ||||||
|           color: #2266FF; |  | ||||||
|  |  | ||||||
|           i, span { |  | ||||||
|             color: #2266FF; |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         span { |  | ||||||
|           font-size: 14px; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         i { |  | ||||||
|           cursor: pointer; |  | ||||||
|           color: #8e9ebf; |  | ||||||
|           font-size: 16px; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       span { |  | ||||||
|         color: #222222; |  | ||||||
|         font-size: 14px; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       :deep( .el-tree ){ |  | ||||||
|         background: transparent; |  | ||||||
|  |  | ||||||
|         .el-tree-node__expand-icon.is-leaf { |  | ||||||
|           color: transparent !important; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         .el-tree-node__content > .el-tree-node__expand-icon { |  | ||||||
|           padding: 4px; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         .el-tree-node__content { |  | ||||||
|           height: 32px; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         .el-tree__empty-text { |  | ||||||
|           color: #222; |  | ||||||
|           font-size: 14px; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         .el-tree-node__children .el-tree-node__content { |  | ||||||
|           height: 32px; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         .el-tree-node__content:hover { |  | ||||||
|           background: #E8EFFF; |  | ||||||
|           color: #222222; |  | ||||||
|           border-radius: 2px; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         .is-current > .el-tree-node__content { |  | ||||||
|           &:hover { |  | ||||||
|             background: #2266FF; |  | ||||||
|             color: #fff; |  | ||||||
|           } |  | ||||||
|  |  | ||||||
|           background: #2266FF; |  | ||||||
|  |  | ||||||
|           span { |  | ||||||
|             color: #fff; |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   :deep( .ai-list__content--right ){ |  | ||||||
|     flex: 1; |  | ||||||
|     min-width: 0; |  | ||||||
|     margin-left: 1px; |  | ||||||
|     box-shadow: none; |  | ||||||
|  |  | ||||||
|     .ai-list__content--right-wrapper { |  | ||||||
|       width: 100%; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,164 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <section class="AppLicence"> |  | ||||||
|     <ai-list> |  | ||||||
|       <ai-title slot="title" title="产品许可" isShowBottomBorder  :instance="instance"></ai-title> |  | ||||||
|       <template #content> |  | ||||||
|         <div class="licence-content"> |  | ||||||
|           <img class="left-img" src="https://cdn.cunwuyun.cn/dvcp/key.png" alt="" /> |  | ||||||
|           <div class="content-right"> |  | ||||||
|             <h3 class="title">产品许可信息</h3> |  | ||||||
|             <p class="mini-title">您当前的版本为Saas专业版,非常感谢您对我们产品的认可与支持!</p> |  | ||||||
|             <div class="info"> |  | ||||||
|               <span class="label">过期时间</span> |  | ||||||
|               <span class="value color-f46" v-if="info.isExpired == 1">{{info.expireDate ? info.expireDate+'(已过期)' : '未激活'}}</span> |  | ||||||
|               <span class="value color-26f" v-else>{{info.expireDate}}</span> |  | ||||||
|             </div> |  | ||||||
|             <div class="info"> |  | ||||||
|               <span class="label">主板序列号</span> |  | ||||||
|               <span class="value">{{info.mainBoard}}</span> |  | ||||||
|             </div> |  | ||||||
|             <div class="info"> |  | ||||||
|               <span class="label">CPU</span> |  | ||||||
|               <span class="value">{{info.cpu}}</span> |  | ||||||
|             </div> |  | ||||||
|             <div class="info"> |  | ||||||
|               <span class="label">MAC地址</span> |  | ||||||
|               <span class="value">{{info.mac}}</span> |  | ||||||
|             </div> |  | ||||||
|             <div class="info mar-b32"> |  | ||||||
|               <span class="label">IP地址</span> |  | ||||||
|               <span class="value">{{info.ip}}</span> |  | ||||||
|             </div> |  | ||||||
|             <el-upload |  | ||||||
|               class="upload-demo" |  | ||||||
|               action |  | ||||||
|               multiple |  | ||||||
|               accept=".lic" |  | ||||||
|               :http-request="uploadFile"> |  | ||||||
|               <div class="btn">上传许可</div> |  | ||||||
|             </el-upload> |  | ||||||
|           </div> |  | ||||||
|         </div> |  | ||||||
|       </template> |  | ||||||
|     </ai-list> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
| <script> |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "AppLicence", |  | ||||||
|   label: "产品许可", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       files: [], |  | ||||||
|       info: {} |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   mounted() { |  | ||||||
|     this.getDetail() |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     getDetail() { |  | ||||||
|       this.instance.post(`/admin/license/detail`).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           this.info = res.data |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     uploadFile: function (file) { |  | ||||||
|       let formData = new FormData(); |  | ||||||
|       formData.append("file", file.file); |  | ||||||
|       this.instance.post(`/admin/license/save`, formData, {withoutToken: false}).then(res => { |  | ||||||
|         if (res && res.code == 0) { |  | ||||||
|           this.$message.success("证书上传成功!"); |  | ||||||
|           this.getDetail() |  | ||||||
|         } |  | ||||||
|       }); |  | ||||||
|     }, |  | ||||||
|   }, |  | ||||||
|  |  | ||||||
| }; |  | ||||||
| </script> |  | ||||||
| <style lang="scss" scoped> |  | ||||||
| .AppLicence { |  | ||||||
|   width: 100%; |  | ||||||
|   height: 100%; |  | ||||||
|   :deep( .ai-list){ |  | ||||||
|     background-color: #F5F6F9; |  | ||||||
|   } |  | ||||||
|   :deep( .ai-list .ai-list__content--right .ai-list__content--right-wrapper){ |  | ||||||
|     background-color: #F5F6F9; |  | ||||||
|     box-shadow: 0 0 0 0; |  | ||||||
|     margin: 0!important; |  | ||||||
|     padding: 0!important; |  | ||||||
|   } |  | ||||||
|   :deep( .el-upload-list){ |  | ||||||
|     display: none; |  | ||||||
|   } |  | ||||||
|   .licence-content{ |  | ||||||
|     display: flex; |  | ||||||
|     margin-top: 30px; |  | ||||||
|     .left-img{ |  | ||||||
|       width: 200px; |  | ||||||
|       height: 200px; |  | ||||||
|     } |  | ||||||
|     .content-right{ |  | ||||||
|       width: 800px; |  | ||||||
|       .title{ |  | ||||||
|         font-size: 24px; |  | ||||||
|         font-family: MicrosoftYaHei-Bold, MicrosoftYaHei; |  | ||||||
|         font-weight: bold; |  | ||||||
|         color: #222; |  | ||||||
|         line-height: 24px; |  | ||||||
|         margin-bottom: 8px; |  | ||||||
|       } |  | ||||||
|       .mini-title{ |  | ||||||
|         font-size: 14px; |  | ||||||
|         font-family: MicrosoftYaHei; |  | ||||||
|         color: #555; |  | ||||||
|         line-height: 22px; |  | ||||||
|         margin-bottom: 20px; |  | ||||||
|       } |  | ||||||
|       .info{ |  | ||||||
|         font-size: 14px; |  | ||||||
|         font-family: MicrosoftYaHei; |  | ||||||
|         line-height: 22px; |  | ||||||
|         margin-bottom: 8px; |  | ||||||
|         display: flex; |  | ||||||
|         color: #222; |  | ||||||
|         .label{ |  | ||||||
|           width: 164px; |  | ||||||
|         } |  | ||||||
|         .value{ |  | ||||||
|           width: calc(100% - 164px); |  | ||||||
|         } |  | ||||||
|         .color-26f{ |  | ||||||
|           color: #26f; |  | ||||||
|         } |  | ||||||
|         .color-f46{ |  | ||||||
|           color: #f46; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|       .mar-b32{ |  | ||||||
|         margin-bottom: 32px; |  | ||||||
|       } |  | ||||||
|       .btn{ |  | ||||||
|         width: 88px; |  | ||||||
|         height: 32px; |  | ||||||
|         line-height: 32px; |  | ||||||
|         text-align: center; |  | ||||||
|         background: linear-gradient(90deg, #299FFF 0%, #0C61FF 100%); |  | ||||||
|         border-radius: 2px; |  | ||||||
|         cursor: pointer; |  | ||||||
|         color: #fff; |  | ||||||
|         font-size: 14px; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,354 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <ai-list class="AppPartyPayment"> |  | ||||||
|     <template slot="title"> |  | ||||||
|       <ai-title title="党费缴纳" isShowBottomBorder :instance="instance"></ai-title> |  | ||||||
|     </template> |  | ||||||
|     <template #content> |  | ||||||
|       <div class="statistics-top"> |  | ||||||
|         <div class="statistics-top__item"> |  | ||||||
|           <span>本月已缴纳党费金额</span> |  | ||||||
|           <h2 style="color: #2266FF;">{{ topTotal['本月缴纳党费'] || 0 }}</h2> |  | ||||||
|         </div> |  | ||||||
|         <div class="statistics-top__item"> |  | ||||||
|           <span>本月已缴纳人数</span> |  | ||||||
|           <h2 style="color: #22AA99;">{{ topTotal['本月已缴纳人数'] || 0  }}</h2> |  | ||||||
|         </div> |  | ||||||
|         <div class="statistics-top__item"> |  | ||||||
|           <span>本月未缴纳党费金额</span> |  | ||||||
|           <h2 style="color: #F8B425">{{ topTotal['本月未缴纳党费'] || 0 }}</h2> |  | ||||||
|         </div> |  | ||||||
|         <div class="statistics-top__item"> |  | ||||||
|           <span>本月未缴纳人数</span> |  | ||||||
|           <h2 style="color: #999;">{{ topTotal['本月未缴纳人数'] || 0 }}</h2> |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|       <div class="content"> |  | ||||||
|         <ai-search-bar> |  | ||||||
|           <template #left> |  | ||||||
|             <ai-party :instance="instance" v-model="search.partyOrgId" :topOrgId="topOrgId" :name.sync="search.partyOrgName" |  | ||||||
|                     style="display:inline-block" @origin="handlePartyOrgSelect" customClicker |  | ||||||
|                     url="/app/partyOrganization/queryAllChildren"> |  | ||||||
|               <el-input size="small" v-model="search.partyOrgName" readonly placeholder="选择党组织"></el-input> |  | ||||||
|             </ai-party> |  | ||||||
|             <el-date-picker v-model="search.ymd" type="month" placeholder="选择日期" size="small" value-format="yyyy-MM" @change="getListInit"></el-date-picker> |  | ||||||
|             <ai-select |  | ||||||
|               v-model="search.status" |  | ||||||
|               @change="getListInit()" |  | ||||||
|               placeholder="状态" |  | ||||||
|               :selectList="dict.getDict('zhishengPartyFeeRecordStatus')"> |  | ||||||
|             </ai-select> |  | ||||||
|           </template> |  | ||||||
|           <template #right> |  | ||||||
|             <el-input size="small" v-model="search.name" placeholder="姓名/身份证" |  | ||||||
|               suffix-icon="iconfont iconSearch" v-throttle="() => {getListInit()}" clearable @clear="search.name = '', getListInit()"/> |  | ||||||
|           </template> |  | ||||||
|         </ai-search-bar> |  | ||||||
|         <ai-search-bar> |  | ||||||
|           <template #left> |  | ||||||
|             <el-button size="small" type="primary" icon="iconfont iconAdd" @click="toAdd('')">新增</el-button> |  | ||||||
|           </template> |  | ||||||
|           <template #right> |  | ||||||
|             <ai-import :instance="instance" :dict="dict" type="appconvenientaddressbook" name="党费缴纳" |  | ||||||
|               @success="getListInit()" importUrl="/app/appdfjnzhisheng/import" url="/app/appdfjnzhisheng/downloadTemplate"> |  | ||||||
|               <el-button icon="iconfont iconImport">导入</el-button> |  | ||||||
|             </ai-import> |  | ||||||
|             <ai-download :instance="instance" url="/app/appdfjnzhisheng/export" :params="search" fileName="党费缴纳" |  | ||||||
|               :disabled="tableData.length == 0"> |  | ||||||
|               <el-button icon="iconfont iconExported" :disabled="tableData.length == 0">导出</el-button> |  | ||||||
|             </ai-download> |  | ||||||
|           </template> |  | ||||||
|         </ai-search-bar> |  | ||||||
|         <ai-table |  | ||||||
|           :tableData="tableData" |  | ||||||
|           :col-configs="colConfigs" |  | ||||||
|           :total="total" |  | ||||||
|           :current.sync="search.current" |  | ||||||
|           :size.sync="search.size" |  | ||||||
|           @getList="getList"> |  | ||||||
|           <el-table-column slot="option" label="操作" align="center" width="160px" fixed="right"> |  | ||||||
|             <template slot-scope="{ row }"> |  | ||||||
|               <div class="table-options"> |  | ||||||
|                 <el-button type="text" title="编辑" @click="edit(row)">编辑</el-button> |  | ||||||
|                 <el-button type="text" title="删除" @click="remove(row)">删除</el-button> |  | ||||||
|               </div> |  | ||||||
|             </template> |  | ||||||
|           </el-table-column> |  | ||||||
|         </ai-table> |  | ||||||
|       </div> |  | ||||||
|       <ai-dialog :visible.sync="dialog" :title="dialogTitle" @closed="$refs.form.resetFields()" @onConfirm="handlePayment"> |  | ||||||
|         <el-form ref="form" :rules="rules" size="small" :model="form" label-width="80px"> |  | ||||||
|           <el-form-item label="党员姓名" prop="name"> |  | ||||||
|             <el-autocomplete ref="poiInput" v-model="form.name" size="small" clearable :fetch-suggestions="handleSearch" |  | ||||||
|               placeholder="请输入党员姓名" @select="handleSelect" :trigger-on-focus="false" style="width:100%;"> |  | ||||||
|               <template slot-scope="{item}"> |  | ||||||
|                 <span style="direction: rtl" v-text="`${item.name}-${item.partyOrgName}(${item.idNumber})`"/> |  | ||||||
|               </template> |  | ||||||
|             </el-autocomplete>  |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="身份证号" prop="idNumber"> |  | ||||||
|             <el-input placeholder="自动带入" v-model="form.idNumber" :disabled="true" size="small"></el-input> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="缴纳状态" prop="status"> |  | ||||||
|             <el-radio-group v-model="form.status"> |  | ||||||
|               <el-radio label="1">已缴纳</el-radio> |  | ||||||
|               <el-radio label="0">未缴纳</el-radio> |  | ||||||
|             </el-radio-group> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="缴纳月份" prop="ymd"> |  | ||||||
|             <el-date-picker v-model="form.ymd" type="month" placeholder="选择年月" size="small" value-format="yyyy-MM"></el-date-picker> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="金额(元)" prop="amount"> |  | ||||||
|             <el-input-number :precision="2" size="small" type="input" v-model="form.amount" clearable placeholder="2位小数"></el-input-number> |  | ||||||
|           </el-form-item> |  | ||||||
|         </el-form> |  | ||||||
|       </ai-dialog> |  | ||||||
|     </template> |  | ||||||
|   </ai-list> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   import {mapState} from 'vuex' |  | ||||||
|   export default { |  | ||||||
|     name: 'AppPartyPayment', |  | ||||||
|     label: '党费缴纳', |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object |  | ||||||
|     }, |  | ||||||
|     data () { |  | ||||||
|       return { |  | ||||||
|         search: { |  | ||||||
|           current: 1, |  | ||||||
|           size: 10, |  | ||||||
|           partyOrgId: '', |  | ||||||
|           partyOrgName: '', |  | ||||||
|           name: '', |  | ||||||
|           status: '', |  | ||||||
|           ymd: '' |  | ||||||
|         }, |  | ||||||
|         total: 0, |  | ||||||
|         tableData: [], |  | ||||||
|         colConfigs: [ |  | ||||||
|           { prop: 'orgName', label: '党组织' }, |  | ||||||
|           { prop: 'name', label: '党员姓名', align: 'center',  }, |  | ||||||
|           { prop: 'idNumber', label: '身份证', align: 'center' }, |  | ||||||
|           { prop: 'ymd', label: '缴纳月份', align: 'center' }, |  | ||||||
|           { prop: 'amount', label: '缴纳党费', align: 'center' }, |  | ||||||
|           { prop: 'status', label: '状态', align: 'center',format: v => this.dict.getLabel('zhishengPartyFeeRecordStatus', v)}, |  | ||||||
|           { slot: 'option'} |  | ||||||
|         ], |  | ||||||
|         topOrgId: '', |  | ||||||
|         dialog: false, |  | ||||||
|         dialogTitle: '', |  | ||||||
|         form: { |  | ||||||
|           name: '', |  | ||||||
|           idNumber: '', |  | ||||||
|           status: '0', |  | ||||||
|           ymd: '', |  | ||||||
|           amount: '', |  | ||||||
|           orgId: '', |  | ||||||
|           orgName: '', |  | ||||||
|           partyId: '' |  | ||||||
|         }, |  | ||||||
|         topTotal: {} |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     computed: { |  | ||||||
|       params () { |  | ||||||
|         return { |  | ||||||
|           ...this.search, |  | ||||||
|           startTime: this.search.type === '3' ? this.date[0] : '', |  | ||||||
|           endTime: this.search.type === '3' ? this.date[1] : '' |  | ||||||
|         } |  | ||||||
|       }, |  | ||||||
|       rules() { |  | ||||||
|         return { |  | ||||||
|           name: [{ required: true, message: '请输入党员姓名', trigger: 'change'}], |  | ||||||
|           idNumber: [{ required: true, message: '请选择党员', trigger: 'change'}], |  | ||||||
|           status: [{ required: true, message: '请选择缴费状态', trigger: 'change'}], |  | ||||||
|           ymd: [{ required: true, message: '请选择缴纳月份', trigger: 'change'}], |  | ||||||
|           amount: [{ required: true, message: '请输入金额', trigger: 'blur'}], |  | ||||||
|         } |  | ||||||
|       }, |  | ||||||
|       ...mapState(['user']), |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     created () { |  | ||||||
|       this.topOrgId = this.user.info.organizationId |  | ||||||
|       this.dict.load('zhishengPartyFeeRecordStatus').then(() => { |  | ||||||
|         this.getList() |  | ||||||
|       }) |  | ||||||
|       this.getTotal() |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       toAdd() { |  | ||||||
|         this.form =  { |  | ||||||
|           name: '', |  | ||||||
|           idNumber: '', |  | ||||||
|           status: '0', |  | ||||||
|           ymd: '', |  | ||||||
|           amount: '', |  | ||||||
|           orgId: '', |  | ||||||
|           orgName: '', |  | ||||||
|           partyId: '' |  | ||||||
|         } |  | ||||||
|         this.dialogTitle = '新增党费信息' |  | ||||||
|         this.dialog = true |  | ||||||
|       }, |  | ||||||
|       edit(row) { |  | ||||||
|         this.form = row |  | ||||||
|         this.dialog = true |  | ||||||
|         this.dialogTitle = '编辑党费信息' |  | ||||||
|       }, |  | ||||||
|       handleSearch(e, cb) { |  | ||||||
|         this.instance.post(`/app/appparty/fuzzyList?name=${e}&size=50`).then((res) => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             cb(res.data) |  | ||||||
|           } |  | ||||||
|         }); |  | ||||||
|       }, |  | ||||||
|       handleSelect(e) { |  | ||||||
|         this.form.name = e.name |  | ||||||
|         this.form.idNumber = e.idNumber |  | ||||||
|         this.form.orgId = e.partyOrgId |  | ||||||
|         this.form.orgName = e.partyOrgName |  | ||||||
|         this.form.partyId = e.id |  | ||||||
|       }, |  | ||||||
|       handlePayment() { |  | ||||||
|         this.$refs.form.validate((valid) => { |  | ||||||
|           if (valid) { |  | ||||||
|             this.instance.post(`/app/appdfjnzhisheng/addOrUpdate`, {...this.form}).then((res) => { |  | ||||||
|               if (res.code == 0) { |  | ||||||
|                 this.$message.success(this.dialogTitle == '编辑党费信息' ? "编辑成功" : "新增成功"); |  | ||||||
|                 this.$refs.form.resetFields() |  | ||||||
|                 this.dialog = false |  | ||||||
|                 this.getListInit() |  | ||||||
|                 this.getTotal() |  | ||||||
|               } |  | ||||||
|             }); |  | ||||||
|           } |  | ||||||
|         }); |  | ||||||
|       }, |  | ||||||
|       handlePartyOrgSelect(e) { |  | ||||||
|         let {isLeaf, name, id} = e?.[0] || {}; |  | ||||||
|         if (isLeaf == 1) { |  | ||||||
|           this.search.partyOrgName = name; |  | ||||||
|           this.search.partyOrgId = id; |  | ||||||
|         } |  | ||||||
|         this.getListInit() |  | ||||||
|       }, |  | ||||||
|       getListInit() { |  | ||||||
|         this.search.current = 1 |  | ||||||
|         this.getList() |  | ||||||
|       }, |  | ||||||
|       getList () { |  | ||||||
|         this.instance.post(`/app/appdfjnzhisheng/list`, null, { |  | ||||||
|           params: { |  | ||||||
|             ...this.search, |  | ||||||
|             orgId: this.search.partyOrgId |  | ||||||
|           } |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             res.data.records.map((item) => { |  | ||||||
|               item.ymd = item.ymd.substring(0, 7) |  | ||||||
|             }) |  | ||||||
|             this.tableData = res.data.records |  | ||||||
|             this.total = res.data.total |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|       remove(row) { |  | ||||||
|         this.$confirm('确定删除该数据?').then(() => { |  | ||||||
|           this.instance.post(`/app/appdfjnzhisheng/delete?ids=${row.id}`).then(res => { |  | ||||||
|             if (res.code == 0) { |  | ||||||
|               this.$message.success('删除成功!') |  | ||||||
|               this.getList() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|       getTotal() { |  | ||||||
|         this.instance.post(`/app/appdfjnzhisheng/statistics`).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.topTotal = res.data |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
|   .AppPartyPayment { |  | ||||||
|  |  | ||||||
|     .bottom { |  | ||||||
|       display: flex; |  | ||||||
|       align-items: center; |  | ||||||
|  |  | ||||||
|       & > .ai-card { |  | ||||||
|         flex: 1; |  | ||||||
|  |  | ||||||
|         &:last-child { |  | ||||||
|           margin-left: 20px; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     :deep( .ai-list__content ){ |  | ||||||
|       padding: 0!important; |  | ||||||
|  |  | ||||||
|       .ai-list__content--right-wrapper { |  | ||||||
|         background: transparent!important; |  | ||||||
|         box-shadow: none!important; |  | ||||||
|         margin: 0!important; |  | ||||||
|         padding: 12px 16px 12px!important; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     :deep( .ai-card) { |  | ||||||
|       .ai-card__body { |  | ||||||
|         padding: 12px 16px; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .statistics-top { |  | ||||||
|       display: flex; |  | ||||||
|       align-items: center; |  | ||||||
|       margin-bottom: 20px; |  | ||||||
|  |  | ||||||
|       & > div { |  | ||||||
|         flex: 1; |  | ||||||
|         height: 96px; |  | ||||||
|         line-height: 1; |  | ||||||
|         margin-right: 20px; |  | ||||||
|         padding: 16px 24px; |  | ||||||
|         background: #FFFFFF; |  | ||||||
|         box-shadow: 0px 4px 6px -2px rgba(15, 15, 21, 0.15); |  | ||||||
|         border-radius: 4px; |  | ||||||
|  |  | ||||||
|         &:last-child { |  | ||||||
|           margin-right: 0; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         h3 { |  | ||||||
|           font-size: 24px; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         span { |  | ||||||
|           display: block; |  | ||||||
|           margin-bottom: 16px; |  | ||||||
|           color: #888888; |  | ||||||
|           font-size: 16px; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .content { |  | ||||||
|       padding: 16px; |  | ||||||
|       background: #FFFFFF; |  | ||||||
|       box-shadow: 0px 4px 6px -2px rgba(15, 15, 21, 0.15); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </style> |  | ||||||
| @@ -1,35 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <section class="AppPartyScore"> |  | ||||||
|     <component :is="currentPage" v-bind="$props"/> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| import PsList from "./psList"; |  | ||||||
| import PsDetail from "./psDetail"; |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "AppPartyScore", |  | ||||||
|   components: {PsDetail, PsList}, |  | ||||||
|   label: "党员积分", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     currentPage() { |  | ||||||
|       return this.$route.query.id ? PsDetail : PsList |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.dict.load("partyIntegralType") |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
| .AppPartyScore { |  | ||||||
|   height: 100%; |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,154 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <section class="psDetail"> |  | ||||||
|     <ai-detail> |  | ||||||
|       <ai-title slot="title" title="积分详情" isShowBottomBorder isShowBack @onBackClick="back"/> |  | ||||||
|       <template #content> |  | ||||||
|         <el-row type="flex"> |  | ||||||
|           <ai-card hideTitle class="staCard fill"> |  | ||||||
|             <template #content> |  | ||||||
|               <div class="color-999" v-text="`姓名`"/> |  | ||||||
|               <b v-text="detail.name"/> |  | ||||||
|             </template> |  | ||||||
|           </ai-card> |  | ||||||
|           <ai-card hideTitle class="staCard fill"> |  | ||||||
|             <template #content> |  | ||||||
|               <div class="color-999" v-text="`学习强国`"/> |  | ||||||
|               <el-button type="text" @click="handleEditLearningIntergral(detail.id)">编辑</el-button> |  | ||||||
|               <b class="color-26f" v-text="detail.learningIntegral||0"/> |  | ||||||
|             </template> |  | ||||||
|           </ai-card> |  | ||||||
|           <ai-card hideTitle class="staCard fill"> |  | ||||||
|             <template slot="content"> |  | ||||||
|               <div class="color-999" v-text="`个人积分`"/> |  | ||||||
|               <b class="color-26f" v-text="detail.integral||0"/> |  | ||||||
|             </template> |  | ||||||
|           </ai-card> |  | ||||||
|           <ai-card hideTitle class="staCard fill"> |  | ||||||
|             <template #content> |  | ||||||
|               <div class="color-999" v-text="`家庭积分`"/> |  | ||||||
|               <b class="color-26f" v-text="detail.familySurplusIntegral||0"/> |  | ||||||
|             </template> |  | ||||||
|           </ai-card> |  | ||||||
|         </el-row> |  | ||||||
|         <ai-card title="余额变动明细"> |  | ||||||
|           <template #content> |  | ||||||
|             <ai-table :tableData="detail.integralInfoList" :isShowPagination="false" :col-configs="colConfigs" |  | ||||||
|                       :dict="dict"/> |  | ||||||
|           </template> |  | ||||||
|         </ai-card> |  | ||||||
|       </template> |  | ||||||
|     </ai-detail> |  | ||||||
|     <ai-dialog :visible.sync="dialog" title="学习强国设置" width="500px" @close="form={}" @onConfirm="submit"> |  | ||||||
|       <el-form :model="form" size="small" ref="DialogForm" :rules="rules" label-width="110px"> |  | ||||||
|         <el-form-item label="学习强国积分" prop="learningIntegral"> |  | ||||||
|           <el-input v-model.number="form.learningIntegral" placeholder="请输入正整数" clearable/> |  | ||||||
|         </el-form-item> |  | ||||||
|       </el-form> |  | ||||||
|     </ai-dialog> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| export default { |  | ||||||
|   name: "psDetail", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       detail: {}, |  | ||||||
|       colConfigs: [ |  | ||||||
|         {label: "时间", prop: "createTime"}, |  | ||||||
|         {label: "类型", prop: "integralType", align: 'center', dict: "partyIntegralType"}, |  | ||||||
|         {label: "变动积分", prop: "integral", align: 'center'}, |  | ||||||
|         {label: "剩余积分", prop: "residualIntegral", align: 'center'}, |  | ||||||
|         {label: "调整说明", prop: "remark"}, |  | ||||||
|       ], |  | ||||||
|       dialog: false, |  | ||||||
|       form: {}, |  | ||||||
|       rules: { |  | ||||||
|         learningIntegral: [ |  | ||||||
|           {required: true, message: "请输入学习强国积分"}, |  | ||||||
|           {pattern: /^\d+$/g, message: "请输入正整数"} |  | ||||||
|         ] |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     getDetail() { |  | ||||||
|       let {id} = this.$route.query |  | ||||||
|       this.instance.post("/app/appparty/getPartyIntegralDetail", null, { |  | ||||||
|         params: {id} |  | ||||||
|       }).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           this.detail = res.data |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     back() { |  | ||||||
|       this.$router.push({}) |  | ||||||
|     }, |  | ||||||
|     submit() { |  | ||||||
|       this.$refs.DialogForm.validate(v => { |  | ||||||
|         if (v) { |  | ||||||
|           this.instance.post("/app/appparty/editLearningIntegral", null,{ |  | ||||||
|             params:this.form |  | ||||||
|           }).then(res => { |  | ||||||
|             if (res?.code == 0) { |  | ||||||
|               this.$message.success("提交成功!") |  | ||||||
|               this.dialog = false |  | ||||||
|               this.getDetail() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     handleEditLearningIntergral(partyMemberId) { |  | ||||||
|       this.dialog = true |  | ||||||
|       this.form = {partyMemberId} |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.getDetail() |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
| .psDetail { |  | ||||||
|   height: 100%; |  | ||||||
|  |  | ||||||
|   .color-999 { |  | ||||||
|     color: #999; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .color-26f { |  | ||||||
|     color: #26f; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   :deep(.staCard ){ |  | ||||||
|     font-size: 14px; |  | ||||||
|  |  | ||||||
|     b { |  | ||||||
|       font-size: 24px; |  | ||||||
|       line-height: 40px; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     & + .staCard { |  | ||||||
|       margin-left: 16px; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .ai-card__body { |  | ||||||
|       position: relative; |  | ||||||
|  |  | ||||||
|       .el-button { |  | ||||||
|         position: absolute; |  | ||||||
|         right: 32px; |  | ||||||
|         top: 6px; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,116 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <section class="psList"> |  | ||||||
|     <ai-list> |  | ||||||
|       <ai-title slot="title" title="党员积分" isShowBottomBorder/> |  | ||||||
|       <template #content> |  | ||||||
|         <ai-search-bar> |  | ||||||
|           <template #right> |  | ||||||
|             <ai-import :instance="instance" name="党员积分" title="导入党员积分" |  | ||||||
|                        suffixName="xlsx" |  | ||||||
|                        url="/app/apppartyintegralinfo/downloadTemplate" |  | ||||||
|                        importUrl="/app/apppartyintegralinfo/import" |  | ||||||
|                        @onSuccess="page.current=1,getTableData()"/> |  | ||||||
|           </template> |  | ||||||
|         </ai-search-bar> |  | ||||||
|         <ai-table :tableData="tableData" :total="page.total" :current.sync="page.current" :size.sync="page.size" |  | ||||||
|                   @getList="getTableData" :col-configs="colConfigs" :dict="dict"> |  | ||||||
|           <el-table-column slot="options" label="操作" fixed="right" align="center"> |  | ||||||
|             <template slot-scope="{row}"> |  | ||||||
|               <el-button type="text" @click="getFamilyByPartyId(row.idNumber)">家庭成员</el-button> |  | ||||||
|               <el-button type="text" @click="showDetail(row.id)">详情</el-button> |  | ||||||
|             </template> |  | ||||||
|           </el-table-column> |  | ||||||
|         </ai-table> |  | ||||||
|       </template> |  | ||||||
|     </ai-list> |  | ||||||
|     <ai-dialog :visible.sync="dialog" title="家庭成员" :customFooter="true" width="780px" @close="familyList=[]"> |  | ||||||
|       <ai-table :tableData="familyList" :isShowPagination="false" :col-configs="familyCols" :dict="dict"/> |  | ||||||
|       <div class="dialog-footer" slot="footer"> |  | ||||||
|         <el-button @click="dialog=false">关 闭</el-button> |  | ||||||
|       </div> |  | ||||||
|     </ai-dialog> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| import {mapState} from "vuex"; |  | ||||||
| import {ID} from "dui/lib/js/utils"; |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "psList", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     ...mapState(['user']), |  | ||||||
|     colConfigs() { |  | ||||||
|       return [ |  | ||||||
|         {label: "姓名", prop: "name"}, |  | ||||||
|         {label: "个人积分", prop: "integral", align: "center"}, |  | ||||||
|         {label: "家庭积分", prop: "familySurplusIntegral", align: "center"}, |  | ||||||
|         {label: "学习强国", prop: "learningIntegral", align: "center"}, |  | ||||||
|         {slot: "options"} |  | ||||||
|       ] |  | ||||||
|     }, |  | ||||||
|     familyCols() { |  | ||||||
|       return [ |  | ||||||
|         { |  | ||||||
|           label: '与户主关系', prop: 'householdRelation', align: 'center', width: 165, |  | ||||||
|           render: (h, {row}) => h('p', this.dict.getLabel('householdRelation', row.householdRelation || "户主")) |  | ||||||
|         }, |  | ||||||
|         {label: '类型', prop: 'residentType', align: 'center', dict: "residentType"}, |  | ||||||
|         {label: '姓名', prop: 'name', align: 'center'}, |  | ||||||
|         {label: '身份证号', render: (h, {row}) => h('p', ID.hideId(row.idNumber)), width: 165}, |  | ||||||
|         {label: '联系电话', prop: 'phone', align: 'center', width: 120} |  | ||||||
|       ] |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       search: {}, |  | ||||||
|       page: {current: 1, size: 10, total: 0}, |  | ||||||
|       tableData: [], |  | ||||||
|       dialog: false, |  | ||||||
|       familyList: [], |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     back() { |  | ||||||
|       this.$router.push({}) |  | ||||||
|     }, |  | ||||||
|     getTableData() { |  | ||||||
|       this.instance.post("/app/appparty/listByPartyIntegral", null, { |  | ||||||
|         params: {...this.page, ...this.search} |  | ||||||
|       }).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           this.tableData = res.data?.records |  | ||||||
|           this.page.total = res.data.total |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     showDetail(id) { |  | ||||||
|       this.$router.push({query: {id}}) |  | ||||||
|     }, |  | ||||||
|     getFamilyByPartyId(idNumber) { |  | ||||||
|       this.instance.post("/app/appresident/queryHomeMember", null, { |  | ||||||
|         params: {idNumber} |  | ||||||
|       }).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           this.familyList = res.data?.family || [] |  | ||||||
|           this.dialog = true |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.getTableData() |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
| .psList { |  | ||||||
|   height: 100%; |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,34 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <section class="AppPartyScoreFlow"> |  | ||||||
|     <component :is="currentPage" v-bind="$props"/> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| import PsfList from "./psfList"; |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "AppPartyScoreFlow", |  | ||||||
|   components: {PsfList}, |  | ||||||
|   label: "党员积分明细", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     currentPage() { |  | ||||||
|       return PsfList |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.dict.load("partyIntegralType") |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
| .AppPartyScoreFlow { |  | ||||||
|   height: 100%; |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,150 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <section class="psfList"> |  | ||||||
|     <ai-list> |  | ||||||
|       <ai-title slot="title" title="党员积分明细" isShowBottomBorder/> |  | ||||||
|       <template #content> |  | ||||||
|         <ai-search-bar> |  | ||||||
|           <template #left> |  | ||||||
|             <el-button type="primary" icon="iconfont iconAdd" @click="dialog=true">添加</el-button> |  | ||||||
|             <el-date-picker type="daterange" placeholder="日期" size="small" clearable v-model="createTime" |  | ||||||
|                             @change="handleSearchTime" start-placeholder="开始时间" end-placeholder="结束时间" |  | ||||||
|                             value-format="yyyy-MM-dd HH:mm:ss" :default-time="['00:00:00','23:59:59']"/> |  | ||||||
|           </template> |  | ||||||
|           <template #right> |  | ||||||
|             <el-input size="small" placeholder="搜索党员" v-model="search.partyName" clearable |  | ||||||
|                       @change="page.current=1,getTableData()" suffix-icon="iconfont iconSearch"/> |  | ||||||
|           </template> |  | ||||||
|         </ai-search-bar> |  | ||||||
|         <ai-table :tableData="tableData" :total="page.total" :current.sync="page.current" :size.sync="page.size" |  | ||||||
|                   @getList="getTableData" :col-configs="colConfigs" :dict="dict"> |  | ||||||
|           <el-table-column slot="options" label="操作" fixed="right" align="center"> |  | ||||||
|             <template slot-scope="{row}"> |  | ||||||
|               <el-button type="text" @click="showDetail(row)">详情</el-button> |  | ||||||
|             </template> |  | ||||||
|           </el-table-column> |  | ||||||
|         </ai-table> |  | ||||||
|       </template> |  | ||||||
|     </ai-list> |  | ||||||
|     <ai-dialog :visible.sync="dialog" title="积分对象" width="600px" @close="form={}" @onConfirm="submit" |  | ||||||
|                :customFooter="!isAdd"> |  | ||||||
|       <el-form v-if="isAdd" :model="form" size="small" ref="DialogForm" :rules="rules" label-width="80px"> |  | ||||||
|         <el-form-item label="选择人员" prop="partyId"> |  | ||||||
|           <ai-select v-model="form.partyId" action="/app/appparty/list" :instance="instance" |  | ||||||
|                      :prop="{label:'name'}"/> |  | ||||||
|         </el-form-item> |  | ||||||
|         <el-form-item label="调整说明" prop="remark"> |  | ||||||
|           <el-input type="textarea" placeholder="请输入" v-model="form.remark" maxlength="100" show-word-limit rows="3" |  | ||||||
|                     clearable/> |  | ||||||
|         </el-form-item> |  | ||||||
|         <el-form-item label="类型" prop="integralType"> |  | ||||||
|           <ai-select v-model="form.integralType" :selectList="dict.getDict('partyIntegralType')"/> |  | ||||||
|         </el-form-item> |  | ||||||
|         <el-form-item label="积分" prop="integral"> |  | ||||||
|           <el-input v-model.number="form.integral" placeholder="请输入正整数" clearable/> |  | ||||||
|         </el-form-item> |  | ||||||
|       </el-form> |  | ||||||
|       <ai-wrapper v-else> |  | ||||||
|         <ai-info-item label="对象" :value="form.partyName"/> |  | ||||||
|         <ai-info-item label="调整说明" :value="form.remark" isLine/> |  | ||||||
|         <ai-info-item label="类型" :value="dict.getLabel('partyIntegralType',form.integralType)"/> |  | ||||||
|         <ai-info-item label="积分" :value="form.integral"/> |  | ||||||
|       </ai-wrapper> |  | ||||||
|     </ai-dialog> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| import {mapState} from "vuex"; |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "psfList", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     ...mapState(['user']), |  | ||||||
|     colConfigs() { |  | ||||||
|       return [ |  | ||||||
|         {label: "对象", prop: "partyName"}, |  | ||||||
|         {label: "调整说明", prop: "remark", align: "center"}, |  | ||||||
|         {label: "时间", prop: "createTime"}, |  | ||||||
|         {label: "类型", prop: "integralType", align: "center", dict: "partyIntegralType"}, |  | ||||||
|         {label: "积分", prop: "integral", align: "center"}, |  | ||||||
|         {slot: "options"} |  | ||||||
|       ] |  | ||||||
|     }, |  | ||||||
|     isAdd() { |  | ||||||
|       return !this.form.id |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       search: {}, |  | ||||||
|       page: {current: 1, size: 10, total: 0}, |  | ||||||
|       tableData: [], |  | ||||||
|       dialog: false, |  | ||||||
|       form: {}, |  | ||||||
|       rules: { |  | ||||||
|         partyId: {required: true, message: "请选择人员"}, |  | ||||||
|         remark: {required: true, message: "请输入调整说明"}, |  | ||||||
|         integralType: {required: true, message: "请选择类型"}, |  | ||||||
|         integral: [ |  | ||||||
|           {required: true, message: "请输入分数"}, |  | ||||||
|           {pattern: /^\d+$/g, message: "请输入正整数"} |  | ||||||
|         ], |  | ||||||
|       }, |  | ||||||
|       createTime: "" |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     getTableData() { |  | ||||||
|       this.instance.post("/app/apppartyintegralinfo/list", null, { |  | ||||||
|         params: {...this.page, ...this.search} |  | ||||||
|       }).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           this.tableData = res.data?.records?.map(e => ({ |  | ||||||
|             ...e, |  | ||||||
|             integral: (e.integralType == 0 ? "-" : '+') + e.integral |  | ||||||
|           })) |  | ||||||
|           this.page.total = res.data.total |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     showDetail(row) { |  | ||||||
|       this.form = JSON.parse(JSON.stringify(row)) |  | ||||||
|       this.dialog = true |  | ||||||
|     }, |  | ||||||
|     submit() { |  | ||||||
|       this.$refs.DialogForm.validate(v => { |  | ||||||
|         if (v) { |  | ||||||
|           let loading = this.$loading({text: "提交中..."}) |  | ||||||
|           this.instance.post("/app/apppartyintegralinfo/addOrUpdate", this.form).then(res => { |  | ||||||
|             loading.close() |  | ||||||
|             if (res?.code == 0) { |  | ||||||
|               this.$message.success("提交成功!") |  | ||||||
|               this.dialog = false |  | ||||||
|               this.getTableData() |  | ||||||
|             } |  | ||||||
|           }).catch(() => loading.close()) |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     handleSearchTime(v) { |  | ||||||
|       this.page.current = 1 |  | ||||||
|       this.search.startTime = v?.[0] |  | ||||||
|       this.search.endTime = v?.[1] |  | ||||||
|       this.getTableData() |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.getTableData() |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
| .psfList { |  | ||||||
|   height: 100%; |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,101 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <section class="conference"> |  | ||||||
|     <ai-list v-if="!showDetail"> |  | ||||||
|       <template slot="title"> |  | ||||||
|         <ai-title title="会议管理"></ai-title> |  | ||||||
|       </template> |  | ||||||
|       <template slot="tabs"> |  | ||||||
|         <el-tabs v-model="currIndex" @tab-click="handleClick"> |  | ||||||
|           <el-tab-pane v-for="(tab,i) in tabs" :key="i" :label="tab.label" :name="String(i)"> |  | ||||||
|             <component :is="tab.comp" v-if="currIndex==i" :ref="currIndex" :instance="instance" :dict="dict" |  | ||||||
|                        :permissions="permissions" @goPage="goPage" :listType="listType" /> |  | ||||||
|           </el-tab-pane> |  | ||||||
|         </el-tabs> |  | ||||||
|       </template> |  | ||||||
|     </ai-list> |  | ||||||
|  |  | ||||||
|     <component v-else :is="currentComp" :instance="instance" :dict="dict" :detail="detailRow" :listType="listType" @gotoEdit="gotoAdd" ></component> |  | ||||||
|  |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
| <script> |  | ||||||
| import addMeeting from './addMeeting'; |  | ||||||
| import detail from './detail' |  | ||||||
| import list from './list' |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: 'AppConference', |  | ||||||
|   label: "会议管理", |  | ||||||
|   components: {addMeeting, detail, list}, |  | ||||||
|   provide() { |  | ||||||
|     return { |  | ||||||
|       top: this |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function, |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       //会议状态,0、草稿;1、未开始;2、进行中;3、已取消;4、已结束 |  | ||||||
|       //参会状态,0、未确认;1、已确认;2、缺席 |  | ||||||
|       currIndex: "0", |  | ||||||
|       currentComp: "", |  | ||||||
|       showDetail: false, |  | ||||||
|       detailRow: {}, |  | ||||||
|       listType: '1', |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   computed:{ |  | ||||||
|     tabs() { |  | ||||||
|       return [ |  | ||||||
|         {label: "我参与的会议", name: "addMeeting", comp: list, detail: detail, permission: ""}, |  | ||||||
|         {label: "我发起的会议", name: "addMeeting",  comp: list, detail: detail, permission: ""}, |  | ||||||
|       ] |  | ||||||
|     }, |  | ||||||
|   }, |  | ||||||
|  |  | ||||||
|   methods: { |  | ||||||
|     goPage(params) { |  | ||||||
|       this.detailRow = params.row |  | ||||||
|       this.currentComp = params.comp |  | ||||||
|  |  | ||||||
|       if(params.comp == 'detail' || params.comp == 'addMeeting') { |  | ||||||
|         this.showDetail = true |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     handleClick() { |  | ||||||
|       if (this.currIndex == 0) { |  | ||||||
|         this.listType = '1' |  | ||||||
|       } else { |  | ||||||
|         this.listType = '0' |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     goBack() { |  | ||||||
|       this.showDetail = false; |  | ||||||
|       if (this.currIndex == '0') { |  | ||||||
|         this.listType = '1' |  | ||||||
|       } else { |  | ||||||
|         this.listType = '0' |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     gotoAdd(obj) { |  | ||||||
|       this.showDetail = true |  | ||||||
|       this.detailRow = obj |  | ||||||
|       this.currentComp = 'addMeeting' |  | ||||||
|     }, |  | ||||||
|   }, |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
| <style lang="scss" scoped> |  | ||||||
|   .conference { |  | ||||||
|     height: 100%; |  | ||||||
|  |  | ||||||
|     :deep( .ai-list__content--right-wrapper ){ |  | ||||||
|       background-color: transparent !important; |  | ||||||
|       box-shadow: none !important; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </style> |  | ||||||
| @@ -1,244 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <ai-detail class="addMeeting"> |  | ||||||
|     <ai-title slot="title" title="发起会议" isShowBack isShowBottomBorder @onBackClick="$parent.goBack"/> |  | ||||||
|     <template #content> |  | ||||||
|       <ai-card title="会议信息"> |  | ||||||
|         <template #content> |  | ||||||
|           <el-form :model="saveData" status-icon ref="ruleForm" :rules="rules" label-width="100px" |  | ||||||
|                    label-position="right"> |  | ||||||
|             <el-form-item label="会议标题:" prop="title"> |  | ||||||
|               <el-input v-model="saveData.title" size="small" placeholder="请输入..." |  | ||||||
|                         :maxlength="30" show-word-limit></el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-row type="flex" justify="space-between"> |  | ||||||
|               <el-form-item label="开始时间:" prop="startTime"> |  | ||||||
|                 <el-date-picker |  | ||||||
|                     :editable="false" |  | ||||||
|                     value-format="yyyy-MM-dd HH:mm:ss" |  | ||||||
|                     v-model="saveData.startTime" |  | ||||||
|                     :picker-options="pickerOptions" |  | ||||||
|                     type="datetime" |  | ||||||
|                     size="small" |  | ||||||
|                     placeholder="选择开始时间"> |  | ||||||
|                 </el-date-picker> |  | ||||||
|               </el-form-item> |  | ||||||
|               <el-form-item label="结束时间:" prop="endTime"> |  | ||||||
|                 <el-date-picker |  | ||||||
|                     :editable="false" |  | ||||||
|                     value-format="yyyy-MM-dd HH:mm:ss" |  | ||||||
|                     v-model="saveData.endTime" |  | ||||||
|                     :picker-options="pickerOptions" |  | ||||||
|                     type="datetime" |  | ||||||
|                     :disabled="!Boolean(saveData.startTime)" |  | ||||||
|                     size="small" |  | ||||||
|                     placeholder="选择结束时间"> |  | ||||||
|                 </el-date-picker> |  | ||||||
|               </el-form-item> |  | ||||||
|             </el-row> |  | ||||||
|             <el-form-item label="会议地点:" prop="address"> |  | ||||||
|               <el-input v-model="saveData.address" size="small" placeholder="请输入..." |  | ||||||
|                         :maxlength="30" show-word-limit></el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="会议内容:" prop="content"> |  | ||||||
|               <el-input v-model="saveData.content" size="small" placeholder="请输入..." |  | ||||||
|                         type="textarea" :rows="8" :maxlength="500" show-word-limit></el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-row type="flex" justify="space-between"> |  | ||||||
|               <el-form-item label="参会提醒:" prop="noticeBefore"> |  | ||||||
|                 <ai-select v-model="saveData.noticeBefore" |  | ||||||
|                            placeholder="请选择" |  | ||||||
|                            :selectList="dict.getDict('meetingNoticeBefore')" |  | ||||||
|                 ></ai-select> |  | ||||||
|               </el-form-item> |  | ||||||
|               <el-form-item label="确认提醒:" prop="noticeAfter"> |  | ||||||
|                 <ai-select v-model="saveData.noticeAfter" |  | ||||||
|                            placeholder="请选择" |  | ||||||
|                            :selectList="dict.getDict('meetingNoticeAfter')" |  | ||||||
|                 ></ai-select> |  | ||||||
|               </el-form-item> |  | ||||||
|             </el-row> |  | ||||||
|             <el-form-item label="会议资料:" prop="files"> |  | ||||||
|               <ai-uploader :instance="instance" @change="handleChange" isShowTip fileType="file" |  | ||||||
|                            v-model="saveData.fileList" |  | ||||||
|                            acceptType=".zip,.rar,.doc,.docx,.xls,.ppt,.pptx,.pdf,.txt,.jpg,.png,.xlsx" |  | ||||||
|                            :limit="9"></ai-uploader> |  | ||||||
|             </el-form-item> |  | ||||||
|           </el-form> |  | ||||||
|         </template> |  | ||||||
|       </ai-card> |  | ||||||
|       <ai-card title="参会人员信息"> |  | ||||||
|         <template #right> |  | ||||||
|           <ai-wechat-selecter slot="append" :instance="instance" v-model="saveData.attendees"> |  | ||||||
|             <el-button type="text" icon="iconfont iconAdd">选择参会人员</el-button> |  | ||||||
|           </ai-wechat-selecter> |  | ||||||
|         </template> |  | ||||||
|         <template #content> |  | ||||||
|           <ai-table |  | ||||||
|               border |  | ||||||
|               :tableData="saveData.attendees" |  | ||||||
|               :colConfigs="colConfigs" |  | ||||||
|               :isShowPagination="false"> |  | ||||||
|             <el-table-column label="操作" slot="option" align="center"> |  | ||||||
|               <template v-slot="{row}"> |  | ||||||
|                 <el-button type="text" title="删除" @click="deletePer(row)">删除</el-button> |  | ||||||
|               </template> |  | ||||||
|             </el-table-column> |  | ||||||
|           </ai-table> |  | ||||||
|         </template> |  | ||||||
|       </ai-card> |  | ||||||
|     </template> |  | ||||||
|     <template #footer> |  | ||||||
|       <el-button @click="$parent.goBack">取消</el-button> |  | ||||||
|       <el-button type="primary" @click="saveFrom(0)">保存草稿</el-button> |  | ||||||
|       <el-button type="primary" @click="saveFrom(1)">保存并发布</el-button> |  | ||||||
|     </template> |  | ||||||
|   </ai-detail> |  | ||||||
| </template> |  | ||||||
| <script> |  | ||||||
| import {mapState} from "vuex"; |  | ||||||
| import moment from 'dayjs' |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "addMeeting", |  | ||||||
|   inject: ['top'], |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function, |  | ||||||
|     detail: Object |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     let endTimePass = (rule, value, callback) => { |  | ||||||
|       if (value) { |  | ||||||
|         if (moment(value).unix() - moment(this.saveData.startTime).unix() > 0) { |  | ||||||
|           callback() |  | ||||||
|         } else { |  | ||||||
|           callback(new Error('结束时间要大于开始时间')); |  | ||||||
|         } |  | ||||||
|       } else { |  | ||||||
|         callback(new Error('请选择结束时间')); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     return { |  | ||||||
|       saveData: { |  | ||||||
|         noticeBefore: '4', |  | ||||||
|         noticeAfter: '0', |  | ||||||
|         attendees: [], |  | ||||||
|         fileList: [] |  | ||||||
|       }, |  | ||||||
|       rules: { |  | ||||||
|         title: [{required: true, message: '请填写会议标题', trigger: 'blur'}], |  | ||||||
|         startTime: [{required: true, message: '请选择开始时间', trigger: 'blur'}], |  | ||||||
|         endTime: [{required: true, validator: endTimePass, trigger: 'change'}], |  | ||||||
|         address: [{required: true, message: '请填写会议地点', trigger: 'blur'}], |  | ||||||
|         // content: [{required: true, message: '请填写会议内容', trigger: 'blur'}], |  | ||||||
|         noticeBefore: [{required: true, message: '请选择参会提醒', trigger: 'blur'}], |  | ||||||
|         noticeAfter: [{required: true, message: '请选择确认提醒', trigger: 'blur'}], |  | ||||||
|       }, |  | ||||||
|       pickerOptions: { |  | ||||||
|         disabledDate(time) { |  | ||||||
|           return time.getTime() < Date.now() - 8.64e7; |  | ||||||
|         } |  | ||||||
|       }, |  | ||||||
|       showEdit: false, |  | ||||||
|       total: 0, |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     handleChange(e) { |  | ||||||
|       this.saveData.fileList = e |  | ||||||
|     }, |  | ||||||
|     deletePer(scope) { |  | ||||||
|       this.$confirm('确认删除此参会人?') |  | ||||||
|       .then(_ => { |  | ||||||
|         if (this.detail.id) { //编辑 |  | ||||||
|  |  | ||||||
|         } else { //新增 |  | ||||||
|           this.saveData.attendees.map((item, index) => { |  | ||||||
|             if (item.id == scope.id) { |  | ||||||
|               this.saveData.attendees.splice(index, 1) |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     saveFrom(status) { |  | ||||||
|       this.$refs["ruleForm"].validate((valid) => { |  | ||||||
|         if (this.saveData.attendees.length == 0) { |  | ||||||
|           return this.$message.error("参会人不能为空!") |  | ||||||
|         } |  | ||||||
|         if (moment(this.saveData.startTime).unix() - moment(Date.now()).unix() < 0) { |  | ||||||
|           return this.$message.error("会议开始时间已过期,请重新选择!"); |  | ||||||
|         } |  | ||||||
|         if (valid) { |  | ||||||
|  |  | ||||||
|           this.saveData.files = [] |  | ||||||
|           this.saveData.fileList.map((item) => { |  | ||||||
|             this.saveData.files.push(item.id) |  | ||||||
|           }) |  | ||||||
|           this.instance.post(`/app/appmeetinginfo/add-update`, { |  | ||||||
|             ...this.saveData, |  | ||||||
|             status: status, |  | ||||||
|           }).then(res => { |  | ||||||
|             if (res.code == 0) { |  | ||||||
|               if (status != 1) { |  | ||||||
|                 this.$message.success("保存草稿成功") |  | ||||||
|               } else { |  | ||||||
|                 this.$message.success("发布成功") |  | ||||||
|               } |  | ||||||
|               this.$parent.goBack(); |  | ||||||
|             } |  | ||||||
|           }); |  | ||||||
|         } |  | ||||||
|       }); |  | ||||||
|     }, |  | ||||||
|     getDetail() { |  | ||||||
|       this.instance.post(`/app/appmeetinginfo/info-id?id=${this.detail.id}`).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           this.saveData = { |  | ||||||
|             ...res.data, |  | ||||||
|           }; |  | ||||||
|           this.saveData.fileList = res.data.files || [] |  | ||||||
|         } |  | ||||||
|       }); |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.dict.load("meetingNoticeAfter", "meetingNoticeBefore").then( |  | ||||||
|         this.$nextTick(() => { |  | ||||||
|           if (JSON.stringify(this.detail) == '{}') { |  | ||||||
|             this.showEdit = false; |  | ||||||
|           } else { |  | ||||||
|             this.showEdit = true; |  | ||||||
|             // this.saveData = {...this.detail}; |  | ||||||
|             // this.compereList = this.saveData.hosts; |  | ||||||
|             // this.saveData.attendees = this.saveData.attendees || []; |  | ||||||
|             this.getDetail() |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|     ) |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     ...mapState(['user']), |  | ||||||
|     headerTitle() { |  | ||||||
|       return this.showEdit ? '修改会议' : '发起会议' |  | ||||||
|     }, |  | ||||||
|     colConfigs() { |  | ||||||
|       return [ |  | ||||||
|         {prop: 'name', align: 'center', label: '姓名'}, |  | ||||||
|         {prop: 'departName', align: 'center', label: '所属单位'}, |  | ||||||
|         {slot: 'option'} |  | ||||||
|       ] |  | ||||||
|     }, |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
| <style lang="scss" scoped> |  | ||||||
| .addMeeting { |  | ||||||
|   :deep( .el-button--text ){ |  | ||||||
|     .iconfont { |  | ||||||
|       color: inherit; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,595 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <section class="meetingDetail detail-content"> |  | ||||||
|     <ai-detail> |  | ||||||
|       <template #title> |  | ||||||
|         <ai-title title="会议详情" isShowBottomBorder isShowBack @onBackClick="$parent.goBack"> |  | ||||||
|           <template #rightBtn> |  | ||||||
|             <p class="conference_top_area" v-if="listType==0"> |  | ||||||
|               <!-- <el-button type="primary" v-if="detail.status==0" @click="changeMeeting('是否立即发布会议?')">立即发布</el-button> --> |  | ||||||
|               <el-button type="primary" v-if="detail.status==1" @click="noticeMetting()">参会提醒</el-button> |  | ||||||
|               <el-button type="primary" v-if="detail.status==0" @click="editMeeting()">修改会议</el-button> |  | ||||||
|               <el-button class="del-btn-list" v-if="detail.status==1" @click="changeMeeting('是否取消会议?')">取消会议</el-button> |  | ||||||
|               <el-button class="iconfont iconDelete del-btn-list" v-if="detail.status==0||detail.status==3" |  | ||||||
|                          @click="changeMeeting('是否删除会议?')">删除会议 |  | ||||||
|               </el-button> |  | ||||||
|             </p> |  | ||||||
|             <!-- v-if="detail.status==0||detail.status==3" --> |  | ||||||
|             <p class="conference_top_area" v-if="listType==1&&info.status==1"> |  | ||||||
|               <el-button @click="toDo" style="width:80px;" class="del-btn-list">待定</el-button> |  | ||||||
|               <el-button @click="innerVisible=true" v-if="info.joinStatus!=2" style="width:80px;" class="del-btn-list"> |  | ||||||
|                 请假 |  | ||||||
|               </el-button> |  | ||||||
|               <el-button type="primary" @click="changeMeeting('是否确认参会?')" v-if="info.joinStatus!=1" style="width:80px;"> |  | ||||||
|                 确认参会 |  | ||||||
|               </el-button> |  | ||||||
|             </p> |  | ||||||
|           </template> |  | ||||||
|         </ai-title> |  | ||||||
|       </template> |  | ||||||
|       <template #content> |  | ||||||
|         <ai-dialog |  | ||||||
|             title="确认请假" |  | ||||||
|             :visible.sync="innerVisible" |  | ||||||
|             @onConfirm="queMeeting('writeInfo')" |  | ||||||
|             @onCancel="innerVisible=false;" @close="$refs.writeInfo.resetFields()" |  | ||||||
|             width="520px"> |  | ||||||
|           <div class="addother_main" style="width:400px;margin:auto;"> |  | ||||||
|             <el-form :model="writeInfo" status-icon ref="writeInfo" label-width="100px" class="demo-ruleForm"> |  | ||||||
|               <el-form-item label="请假原因:" prop="reason" autocomplete="off" |  | ||||||
|                             :rules="{ |  | ||||||
|                                         required: true, message: '请假原因不能为空', trigger: 'blur' |  | ||||||
|                                     }" |  | ||||||
|               > |  | ||||||
|                 <el-input v-model.trim="writeInfo.reason" autocomplete="off" size="mini" placeholder="请输入..." |  | ||||||
|                           type="textarea" :rows="4" :maxlength="100" show-word-limit></el-input> |  | ||||||
|               </el-form-item> |  | ||||||
|  |  | ||||||
|             </el-form> |  | ||||||
|           </div> |  | ||||||
|         </ai-dialog> |  | ||||||
|         <ai-card title="会议说明"> |  | ||||||
|           <template slot="content"> |  | ||||||
|             <ai-wrapper class="mar-t16" label-width="70px" :columnsNumber="1"> |  | ||||||
|               <ai-info-item label="会议标题:"><span>{{ info.title }}</span></ai-info-item> |  | ||||||
|             </ai-wrapper> |  | ||||||
|             <ai-wrapper class="mar-t16" label-width="70px" :columnsNumber="2"> |  | ||||||
|               <ai-info-item label="发起单位:" :value="info.unitName"> |  | ||||||
|               </ai-info-item> |  | ||||||
|               <ai-info-item label="发起人:" :value="info.userName"> |  | ||||||
|               </ai-info-item> |  | ||||||
|             </ai-wrapper> |  | ||||||
|             <ai-wrapper class="mar-t16" label-width="70px" :columnsNumber="1"> |  | ||||||
|               <!-- <ai-info-item label="会议状态:" v-if="xq.joinStatus==1&&listType==1"><span>{{ xq.joinStatus }}</span> |  | ||||||
|               </ai-info-item> --> |  | ||||||
|               <ai-info-item label="发起时间:"><span>{{ info.createTime }}</span></ai-info-item> |  | ||||||
|             </ai-wrapper> |  | ||||||
|             <ai-wrapper class="mar-t16" label-width="70px" :columnsNumber="2"> |  | ||||||
|               <ai-info-item label="开始时间:"><span>{{ info.startTime }}</span></ai-info-item> |  | ||||||
|               <ai-info-item label="结束时间:"><span>{{ info.endTime }}</span></ai-info-item> |  | ||||||
|             </ai-wrapper> |  | ||||||
|             <ai-wrapper class="mar-t16" label-width="70px" :columnsNumber="2"> |  | ||||||
|               <ai-info-item label="参会提醒:"><span>{{ |  | ||||||
|                   dict.getLabel("meetingNoticeBefore", info.noticeBefore) || "-" |  | ||||||
|                 }}</span></ai-info-item> |  | ||||||
|               <ai-info-item label="确认提醒:"><span>{{ |  | ||||||
|                   dict.getLabel("meetingNoticeAfter", info.noticeAfter) || "-" |  | ||||||
|                 }}</span> |  | ||||||
|               </ai-info-item> |  | ||||||
|             </ai-wrapper> |  | ||||||
|             <ai-wrapper class="mar-t16" label-width="70px" :columnsNumber="1"> |  | ||||||
|               <ai-info-item label="会议地点:"><span>{{ info.address }}</span></ai-info-item> |  | ||||||
|             </ai-wrapper> |  | ||||||
|             <ai-wrapper class="mar-t16" label-width="70px" :columnsNumber="1"> |  | ||||||
|               <ai-info-item label="会议内容:"><span v-html="info.content"></span></ai-info-item> |  | ||||||
|             </ai-wrapper> |  | ||||||
|           </template> |  | ||||||
|         </ai-card> |  | ||||||
|         <ai-card title="会议资料"> |  | ||||||
|           <template slot="content"> |  | ||||||
|             <ai-file-list :fileList="info.files" :fileOps="{name: 'name', size: 'fileSizeStr'}"></ai-file-list> |  | ||||||
|           </template> |  | ||||||
|         </ai-card> |  | ||||||
|         <ai-card title="参会名单"> |  | ||||||
|           <template slot="content"> |  | ||||||
|             <ai-search-bar bottomBorder> |  | ||||||
|               <template #left> |  | ||||||
|                 <el-select v-model="search.joinStatus" placeholder="确认状态" size="small" clearable class="vc-input-160" @change="searchMeetinguser"> |  | ||||||
|                   <el-option |  | ||||||
|                       v-for="(item,k) in confirmStatus" |  | ||||||
|                       :key="k" |  | ||||||
|                       :label="item.label" |  | ||||||
|                       :value="k"> |  | ||||||
|                   </el-option> |  | ||||||
|                 </el-select> |  | ||||||
|               </template> |  | ||||||
|               <template #right> |  | ||||||
|                 <!-- <ai-download :instance="instance" url="/app/appepidemicbackhomerecord/export" fileName="参会名单"> |  | ||||||
|                   <el-button icon="iconfont iconExported">导出</el-button> |  | ||||||
|                 </ai-download> --> |  | ||||||
|               </template> |  | ||||||
|             </ai-search-bar> |  | ||||||
|             <ai-table |  | ||||||
|                 :tableData="info.attendees" |  | ||||||
|                 :colConfigs="colConfigs" |  | ||||||
|                 style="margin-top: 12px;" |  | ||||||
|                 :isShowPagination="false"> |  | ||||||
|               <el-table-column slot="meetingUserName" |  | ||||||
|                                label="姓名" |  | ||||||
|                                align="center" |  | ||||||
|                                show-overflow-tooltip> |  | ||||||
|                 <div slot-scope="{row}"> |  | ||||||
|                   <span>{{ row.meetingUserName }}</span> |  | ||||||
|                 </div> |  | ||||||
|               </el-table-column> |  | ||||||
|  |  | ||||||
|               <el-table-column slot="meetingUnitName" |  | ||||||
|                                label="所属部门" |  | ||||||
|                                align="center" |  | ||||||
|                                show-overflow-tooltip> |  | ||||||
|                 <div slot-scope="{row}"> |  | ||||||
|                   <span>{{ row.meetingUnitName }}</span> |  | ||||||
|                 </div> |  | ||||||
|               </el-table-column> |  | ||||||
|  |  | ||||||
|               <el-table-column slot="joinStatus" |  | ||||||
|                                prop="joinStatus" |  | ||||||
|                                label="确认状态" |  | ||||||
|                                align="center" |  | ||||||
|                                show-overflow-tooltip> |  | ||||||
|                 <div slot-scope="{row}"> |  | ||||||
|                   <p style="color:rgba(255,68,102,1);display:flex;justify-content:center;" v-if="row.joinStatus==2"> |  | ||||||
|                     请假<i class="el-icon-warning" :title="row.absence" style="cursor: pointer;"></i> |  | ||||||
|                   </p> |  | ||||||
|                   <span v-else :style="{color:confirmStatus[row.joinStatus].color}" |  | ||||||
|                         v-text="confirmStatus[row.joinStatus].label"/> |  | ||||||
|                 </div> |  | ||||||
|               </el-table-column> |  | ||||||
|               <el-table-column slot="option" |  | ||||||
|                                label="操作" |  | ||||||
|                                align="center" |  | ||||||
|                                v-if="listType==0" |  | ||||||
|                                show-overflow-tooltip> |  | ||||||
|                 <div slot-scope="{row}" v-if="row.joinStatus==0"> |  | ||||||
|                   <span class="el-icon-message-solid" style="cursor: pointer;" title="参会提醒" |  | ||||||
|                         @click="noticeMetting(row.meetingUserId)" v-if="detail.status==1"></span> |  | ||||||
|                 </div> |  | ||||||
|               </el-table-column> |  | ||||||
|             </ai-table> |  | ||||||
|           </template> |  | ||||||
|         </ai-card> |  | ||||||
|       </template> |  | ||||||
|     </ai-detail> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
| <script> |  | ||||||
| import {mapState} from "vuex"; |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: 'meetingDetail', |  | ||||||
|   inject: ['top'], |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function, |  | ||||||
|     detail: Object, |  | ||||||
|     listType: String |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       navId: '1', |  | ||||||
|       info: {}, |  | ||||||
|       total: 0, |  | ||||||
|       writeInfo: {reason: ''}, |  | ||||||
|       meetingUserList: [], |  | ||||||
|       innerVisible: false, |  | ||||||
|       search: {joinStatus: ''} |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.dict.load("meetingNoticeAfter", "meetingNoticeBefore").then(() => this.searchDetail(this.detail.id)) |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     ...mapState(['user']), |  | ||||||
|     colConfigs() { |  | ||||||
|       return [ |  | ||||||
|         { |  | ||||||
|           slot: 'meetingUserName' |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|           slot: 'meetingUnitName' |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|           slot: 'joinStatus', |  | ||||||
|         }, |  | ||||||
|         {prop: 'signInStatus', align: 'center', label: '签到', format: v => v === '1' ? '已签到' : '未签到'}, |  | ||||||
|         { |  | ||||||
|           slot: 'option', |  | ||||||
|         } |  | ||||||
|       ] |  | ||||||
|     }, |  | ||||||
|     confirmStatus() { |  | ||||||
|       return { |  | ||||||
|         0: {label: '未确认', color: "rgba(255,136,34,1)"}, |  | ||||||
|         1: {label: '已确认', color: "rgba(34,102,255,1)"}, |  | ||||||
|         2: {label: '请假', color: "rgba(255,68,102,1)"}, |  | ||||||
|         3: {label: '待定', color: "rgba(255,136,34,1)"}, |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     toDo() { |  | ||||||
|       this.$confirm("是否确认待定会议?").then(_ => { |  | ||||||
|         this.instance.post("/app/appmeetinginfo/tobeConfirm", null, { |  | ||||||
|           params: { |  | ||||||
|             meetingId: this.detail.id, |  | ||||||
|           } |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.$message.success("会议待定"); |  | ||||||
|             setTimeout(_ => { |  | ||||||
|               this.$parent.goBack(); |  | ||||||
|             }, 800) |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     searchMeetinguser() { |  | ||||||
|       this.instance.post(`/app/appmeetinguser/list`, null, { |  | ||||||
|         params: {...this.search, size: 999, meetingId: this.info.id} |  | ||||||
|       }).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           this.info.attendees = res.data.records; |  | ||||||
|           this.total = res.data.total; |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|       }); |  | ||||||
|     }, |  | ||||||
|     searchDetail(id) { |  | ||||||
|       this.instance.post(`/app/appmeetinginfo/info-id`, null, { |  | ||||||
|         params: {id} |  | ||||||
|       }).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           let {files = [], content} = res.data |  | ||||||
|           content = content.replace(/(\r\n)|(\n)/g, "<br>") |  | ||||||
|           this.info = {...res.data, content, files}; |  | ||||||
|           this.searchMeetinguser() |  | ||||||
|         } |  | ||||||
|       }); |  | ||||||
|     }, |  | ||||||
|     changeMeeting(title, id) { |  | ||||||
|       this.$confirm(title, { |  | ||||||
|         type: 'warning' |  | ||||||
|       }).then(() => { |  | ||||||
|         if (title == '是否立即发布会议?') { |  | ||||||
|           this.fbMeeting(); |  | ||||||
|         } else if (title == '是否删除会议?') { |  | ||||||
|           this.sdMeeting(); |  | ||||||
|         } else if (title == '是否取消会议?') { |  | ||||||
|           this.qxMeeting(); |  | ||||||
|         } else if (title == '是否确认参会?') { |  | ||||||
|           this.qrMeeting(); |  | ||||||
|         } else if (title == '是否删除此参会人员?') { |  | ||||||
|           this.deleteMeetingPer(id) |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     deleteMeetingPer(id) { |  | ||||||
|       this.instance.post(`/app/appmeetinguser/delete`, null, |  | ||||||
|           { |  | ||||||
|             params: { |  | ||||||
|               id |  | ||||||
|             } |  | ||||||
|           } |  | ||||||
|       ).then(res => { |  | ||||||
|  |  | ||||||
|         if (res && res.code == 0) { |  | ||||||
|           this.$message.success("删除成功!"); |  | ||||||
|           this.searchMeetinguser(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|       }); |  | ||||||
|     }, |  | ||||||
|     queMeeting(formName) { |  | ||||||
|       this.$refs[formName].validate((valid) => { |  | ||||||
|         if (valid) { |  | ||||||
|           this.instance.post(`/app/appmeetinginfo/absent`, null, |  | ||||||
|               { |  | ||||||
|                 params: { |  | ||||||
|                   meetingId: this.detail.id, |  | ||||||
|                   reason: this.writeInfo.reason |  | ||||||
|                 } |  | ||||||
|               } |  | ||||||
|           ).then(res => { |  | ||||||
|  |  | ||||||
|             if (res && res.code == 0) { |  | ||||||
|               this.innerVisible = false; |  | ||||||
|               this.$parent.goBack(); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|           }); |  | ||||||
|         } else { |  | ||||||
|           return false; |  | ||||||
|         } |  | ||||||
|       }); |  | ||||||
|  |  | ||||||
|     }, |  | ||||||
|     qrMeeting() { |  | ||||||
|       this.instance.post(`/app/appmeetinginfo/confirm`, null, |  | ||||||
|           { |  | ||||||
|             params: { |  | ||||||
|               meetingId: this.detail.id |  | ||||||
|  |  | ||||||
|             } |  | ||||||
|           } |  | ||||||
|       ).then(res => { |  | ||||||
|  |  | ||||||
|         if (res && res.code == 0) { |  | ||||||
|           this.$message.success("确认参会成功!") |  | ||||||
|           this.$parent.goBack(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|       }); |  | ||||||
|     }, |  | ||||||
|     noticeMetting(meetingUserId) { |  | ||||||
|       this.instance.post(`/app/appmeetinginfo/notice`, null, { |  | ||||||
|         params: { |  | ||||||
|           meetingId: this.detail.id, noticeALL: !meetingUserId, meetingUserId |  | ||||||
|         } |  | ||||||
|       }).then(res => { |  | ||||||
|         if (res && res.code == 0) { |  | ||||||
|           this.$message.success("提醒成功!") |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|       }); |  | ||||||
|     }, |  | ||||||
|     fbMeeting() { |  | ||||||
|       this.instance.post(`/app/appmeetinginfo/release`, null, |  | ||||||
|           { |  | ||||||
|             params: { |  | ||||||
|               meetingId: this.detail.id |  | ||||||
|             } |  | ||||||
|           } |  | ||||||
|       ).then(res => { |  | ||||||
|  |  | ||||||
|         if (res && res.code == 0) { |  | ||||||
|           this.$message.success("发布成功!") |  | ||||||
|           this.$parent.goBack(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|       }); |  | ||||||
|  |  | ||||||
|     }, |  | ||||||
|     sdMeeting() { |  | ||||||
|       this.instance.post(`/app/appmeetinginfo/delete`, null, |  | ||||||
|           { |  | ||||||
|             params: { |  | ||||||
|               meetingId: this.detail.id |  | ||||||
|             } |  | ||||||
|           } |  | ||||||
|       ).then(res => { |  | ||||||
|  |  | ||||||
|         if (res && res.code == 0) { |  | ||||||
|           this.$message.success("删除成功!"); |  | ||||||
|           this.$parent.goBack(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|       }); |  | ||||||
|     }, |  | ||||||
|     qxMeeting() { |  | ||||||
|       this.instance.post(`/app/appmeetinginfo/cancel`, null, |  | ||||||
|           { |  | ||||||
|             params: { |  | ||||||
|               meetingId: this.detail.id |  | ||||||
|             } |  | ||||||
|           } |  | ||||||
|       ).then(res => { |  | ||||||
|  |  | ||||||
|         if (res && res.code == 0) { |  | ||||||
|           this.$message.success("取消会议成功!"); |  | ||||||
|           this.$parent.goBack(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|       }); |  | ||||||
|     }, |  | ||||||
|     editMeeting() { |  | ||||||
|       this.$parent.goBack(); |  | ||||||
|       this.$emit('gotoEdit', this.info) |  | ||||||
|     }, |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
| <style lang="scss" scoped> |  | ||||||
| .meetingDetail { |  | ||||||
|   width: 100%; |  | ||||||
|   height: 100%; |  | ||||||
|   background: rgba(255, 255, 255, 1); |  | ||||||
|  |  | ||||||
|   .conference_top_area { |  | ||||||
|     display: flex; |  | ||||||
|     align-items: center; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .user-search { |  | ||||||
|     width: 100%; |  | ||||||
|     height: 48px; |  | ||||||
|     display: flex; |  | ||||||
|     justify-content: space-between; |  | ||||||
|     align-items: center; |  | ||||||
|  |  | ||||||
|     .float-right { |  | ||||||
|       width: calc(100% - 200px); |  | ||||||
|       text-align: right; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .input-162 { |  | ||||||
|       display: inline-block; |  | ||||||
|       width: 162px; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .content { |  | ||||||
|     width: 1000px; |  | ||||||
|     height: calc(100% - 50px); |  | ||||||
|     overflow: hidden; |  | ||||||
|     margin: auto; |  | ||||||
|     display: flex; |  | ||||||
|     justify-content: space-around; |  | ||||||
|  |  | ||||||
|     .content-left { |  | ||||||
|       width: 160px; |  | ||||||
|       height: 100%; |  | ||||||
|  |  | ||||||
|       .content-left-nav { |  | ||||||
|         width: 158px; |  | ||||||
|         background-color: #ffffff; |  | ||||||
|         border-radius: 4px; |  | ||||||
|         border: solid 1px #eeeeee; |  | ||||||
|         margin-top: 56px; |  | ||||||
|         overflow: hidden; |  | ||||||
|  |  | ||||||
|         li { |  | ||||||
|           height: 48px; |  | ||||||
|           line-height: 48px; |  | ||||||
|           padding-left: 24px; |  | ||||||
|           font-size: 14px; |  | ||||||
|           font-weight: normal; |  | ||||||
|           font-stretch: normal; |  | ||||||
|           letter-spacing: 0; |  | ||||||
|           color: #666666; |  | ||||||
|           cursor: pointer; |  | ||||||
|           border-left: 3px solid transparent; |  | ||||||
|  |  | ||||||
|           &:hover { |  | ||||||
|             border-left: 3px solid #5088ff; |  | ||||||
|           } |  | ||||||
|  |  | ||||||
|           a { |  | ||||||
|             display: block; |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         .navActive { |  | ||||||
|           border-left: 3px solid #5088ff; |  | ||||||
|           color: #5088ff; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .content-right { |  | ||||||
|       width: 780px; |  | ||||||
|       height: calc(100% - 80px); |  | ||||||
|       overflow-y: auto; |  | ||||||
|       margin-left: 40px; |  | ||||||
|       box-sizing: border-box; |  | ||||||
|       overflow-x: hidden; |  | ||||||
|  |  | ||||||
|       .content-right-title { |  | ||||||
|         width: 780px; |  | ||||||
|         height: 56px; |  | ||||||
|         margin-bottom: 16px; |  | ||||||
|         box-shadow: inset 0px -1px 0px 0px #dad5d5; |  | ||||||
|         display: flex; |  | ||||||
|         justify-content: space-between; |  | ||||||
|         align-items: center; |  | ||||||
|  |  | ||||||
|         span { |  | ||||||
|           display: block; |  | ||||||
|           width: 150px; |  | ||||||
|           height: 56px; |  | ||||||
|           line-height: 56px; |  | ||||||
|           color: #333333; |  | ||||||
|           font-weight: bold; |  | ||||||
|  |  | ||||||
|           &:nth-of-type(2) { |  | ||||||
|             text-align: right; |  | ||||||
|             width: 200px; |  | ||||||
|           } |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .flie { |  | ||||||
|         width: 100%; |  | ||||||
|         height: 40px; |  | ||||||
|         line-height: 40px; |  | ||||||
|         padding: 0 8px; |  | ||||||
|         box-sizing: border-box; |  | ||||||
|         display: flex; |  | ||||||
|         align-items: center; |  | ||||||
|         justify-content: space-between; |  | ||||||
|         font-size: 14px; |  | ||||||
|         color: rgba(51, 51, 51, 1); |  | ||||||
|         background: rgba(255, 255, 255, 1); |  | ||||||
|         border-radius: 4px; |  | ||||||
|         border: 1px solid rgba(208, 212, 220, 1); |  | ||||||
|         margin-bottom: 16px; |  | ||||||
|         cursor: pointer; |  | ||||||
|  |  | ||||||
|         p { |  | ||||||
|           display: flex; |  | ||||||
|           justify-content: flex-start; |  | ||||||
|           align-items: center |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .meeting_name { |  | ||||||
|         width: 100%; |  | ||||||
|         padding-bottom: 25px; |  | ||||||
|         font-size: 16px; |  | ||||||
|         box-shadow: inset 0px -1px 0px 0px #dad5d5; |  | ||||||
|         position: relative; |  | ||||||
|         overflow: hidden; |  | ||||||
|  |  | ||||||
|         .title { |  | ||||||
|           color: #333333; |  | ||||||
|           height: 28px; |  | ||||||
|           line-height: 28px; |  | ||||||
|           margin-left: 0; |  | ||||||
|           font-weight: bold; |  | ||||||
|           margin-top: 14px; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         ul { |  | ||||||
|           overflow: hidden; |  | ||||||
|  |  | ||||||
|           li { |  | ||||||
|             width: 33.3%; |  | ||||||
|             float: left; |  | ||||||
|             line-height: 28px; |  | ||||||
|             font-size: 14px; |  | ||||||
|  |  | ||||||
|             span { |  | ||||||
|               width: 70px; |  | ||||||
|               display: block; |  | ||||||
|               float: left; |  | ||||||
|               color: rgba(153, 153, 153, 1) |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             p { |  | ||||||
|               width: calc(100% - 70px); |  | ||||||
|               float: left; |  | ||||||
|               color: rgba(51, 51, 51, 1); |  | ||||||
|             } |  | ||||||
|           ; |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         .svg { |  | ||||||
|           width: 88px; |  | ||||||
|           height: 88px; |  | ||||||
|           position: absolute; |  | ||||||
|           right: -20px; |  | ||||||
|           bottom: -20px; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,259 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <ai-list isTabs> |  | ||||||
|     <template #content> |  | ||||||
|       <ai-search-bar> |  | ||||||
|         <template #left> |  | ||||||
|           <el-button type="primary" @click="addMetting()">发起会议</el-button> |  | ||||||
|           <ai-select |  | ||||||
|               v-model="search.meetingStatus" |  | ||||||
|               @change="getTableData()" |  | ||||||
|               placeholder="会议状态" |  | ||||||
|               :selectList="dict.getDict($parent.name==0 ? 'meetingStatusSelect' : 'meetingStatus')" |  | ||||||
|           ></ai-select> |  | ||||||
|           <ai-select |  | ||||||
|               v-if="$parent.name==0" |  | ||||||
|               v-model="search.confirmStatus" |  | ||||||
|               @change="getTableData()" |  | ||||||
|               placeholder="确认状态" |  | ||||||
|               :selectList="dict.getDict('confirmStatus')" |  | ||||||
|           ></ai-select> |  | ||||||
|         </template> |  | ||||||
|         <template #right> |  | ||||||
|           <el-input |  | ||||||
|             v-model="search.param" |  | ||||||
|             v-throttle="() => {search.current=1,getTableData()}" |  | ||||||
|             @keyup.enter.native="search.current=1,getTableData()" |  | ||||||
|             placeholder="会议标题/地点" |  | ||||||
|             size="small" suffix-icon="iconfont iconSearch" clearable @clear="getTableData()"></el-input> |  | ||||||
|         </template> |  | ||||||
|       </ai-search-bar> |  | ||||||
|       <div class="list_main"> |  | ||||||
|         <div class="no-data" style="height:160px;" v-if="tableData.length==0"></div> |  | ||||||
|         <ul v-if="tableData.length>0"> |  | ||||||
|           <li v-for="(item,index) in tableData" :key="index" @click="goDetail(item)"> |  | ||||||
|             <p> |  | ||||||
|               <span class="conference_title">{{ item.title }}</span> |  | ||||||
|               <span class="time" v-if="item.status==1">{{ item.expirationTime }}</span> |  | ||||||
|             </p> |  | ||||||
|             <p style="width:80%;"> |  | ||||||
|               <el-row type="flex" align="middle" class="unit">发起人:{{ item.userName }} |  | ||||||
|               </el-row> |  | ||||||
|               <el-row type="flex" align="middle" class="unit">发起单位:{{ item.unitName }} |  | ||||||
|               </el-row> |  | ||||||
|             </p> |  | ||||||
|             <p style="width:80%;"> |  | ||||||
|               <span class="unit">会议时间:{{ item.startTime.substring(0, 16) + '至' + item.endTime.substring(0, 16) }}</span> |  | ||||||
|               <el-tooltip :content="item.address" placement="top-start" effect="light"> |  | ||||||
|                 <span class="unit" v-if="item.address.length>12">会议地点:{{ |  | ||||||
|                     item.address.substring(0, 12) + '....' |  | ||||||
|                   }}</span> |  | ||||||
|                 <span class="unit" v-else>会议地点:{{ item.address }}</span> |  | ||||||
|               </el-tooltip> |  | ||||||
|             </p> |  | ||||||
|             <!-- <p style="width:80%;"> |  | ||||||
|                   <span |  | ||||||
|                     class="unit">会议时间:{{ |  | ||||||
|                       item.startTime.substring(0, 16) + '至' + item.endTime.substring(0, 16) |  | ||||||
|                     }}</span> |  | ||||||
|               <el-tooltip :content="item.address" placement="top-start" effect="light"> |  | ||||||
|                     <span class="unit address" |  | ||||||
|                           v-if="item.address.length>12">会议地点:{{ item.address.substring(0, 12) + '....' }}</span> |  | ||||||
|                 <span class="unit address" v-else>会议地点:{{ item.address }}</span> |  | ||||||
|               </el-tooltip> |  | ||||||
|             </p> --> |  | ||||||
|             <h5 :class="{color0:item.status==0,color1:item.status==1,color2:item.status==2,color3:item.status==3,color4:item.status==4}"> |  | ||||||
|               <span v-if="item.status==0">草稿箱</span> |  | ||||||
|               <span v-if="item.status==1">未开始</span> |  | ||||||
|               <span v-if="item.status==2">进行中</span> |  | ||||||
|               <span v-if="item.status==3">已取消</span> |  | ||||||
|               <span v-if="item.status==4">已结束</span> |  | ||||||
|             </h5> |  | ||||||
|             <ai-icon class="svg" v-if="item.joinStatus==0" type="svg" icon="iconunidentified"/> |  | ||||||
|             <ai-icon class="svg" v-else-if="item.joinStatus==1" type="svg" icon="iconidentified"/> |  | ||||||
|             <ai-icon class="svg" v-else-if="item.joinStatus==2" type="svg" icon="iconyiqingjia"/> |  | ||||||
|             <ai-icon class="svg" v-else-if="item.joinStatus==3" type="svg" icon="icondaiding"/> |  | ||||||
|           </li> |  | ||||||
|         </ul> |  | ||||||
|       </div> |  | ||||||
|       <div class="pagination" v-if="tableData.length>0"> |  | ||||||
|         <el-pagination |  | ||||||
|             @current-change="handleCurrentChange" |  | ||||||
|             @size-change="handleSizeChange" |  | ||||||
|             background |  | ||||||
|             :current-page.sync="search.current" |  | ||||||
|             :page-sizes="[5, 10, 50, 100,200]" |  | ||||||
|             :page-size="search.size" |  | ||||||
|             layout="total,prev, pager, next,sizes,jumper" |  | ||||||
|             :total="total"> |  | ||||||
|         </el-pagination> |  | ||||||
|       </div> |  | ||||||
|     </template> |  | ||||||
|   </ai-list> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| export default { |  | ||||||
|   name: "list", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function, |  | ||||||
|     listType: String |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       search: { |  | ||||||
|         meetingStatus: '', |  | ||||||
|         confirmStatus: '', |  | ||||||
|         param: '', |  | ||||||
|         current: 1, |  | ||||||
|         size: 10, |  | ||||||
|         listType: '' |  | ||||||
|       }, |  | ||||||
|       tableData: [], |  | ||||||
|       total: 0, |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     goDetail(item) { |  | ||||||
|       this.$emit('goPage', { |  | ||||||
|         row: item, |  | ||||||
|         comp: 'detail' |  | ||||||
|       }); |  | ||||||
|     }, |  | ||||||
|     addMetting() { |  | ||||||
|       this.$emit('goPage', { |  | ||||||
|         row: {}, |  | ||||||
|         comp: 'addMeeting' |  | ||||||
|       }); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     getTableData() { |  | ||||||
|       this.instance.post(`/app/appmeetinginfo/list`, null, { |  | ||||||
|         params: { |  | ||||||
|           ...this.search, |  | ||||||
|           listType: this.listType |  | ||||||
|         } |  | ||||||
|       }).then(res => { |  | ||||||
|         if (res && res.data) { |  | ||||||
|           this.tableData = res.data.records; |  | ||||||
|           this.total = res.data.total; |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|       }); |  | ||||||
|     }, |  | ||||||
|     handleCurrentChange(val) { |  | ||||||
|       this.search.current = val; |  | ||||||
|       this.getTableData(); |  | ||||||
|     }, |  | ||||||
|     handleSizeChange(val) { |  | ||||||
|       this.search.size = val; |  | ||||||
|       this.getTableData(); |  | ||||||
|     }, |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.dict.load("confirmStatus", "meetingStatus", "meetingStatusSelect").then(_ => this.getTableData()) |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
| .list_main { |  | ||||||
|   width: 100%; |  | ||||||
|  |  | ||||||
|   ul { |  | ||||||
|     overflow: hidden; |  | ||||||
|     padding: 0; |  | ||||||
|     margin: 0; |  | ||||||
|  |  | ||||||
|     li { |  | ||||||
|       width: 100%; |  | ||||||
|       height: 107px; |  | ||||||
|       background: rgba(255, 255, 255, 1); |  | ||||||
|       border-radius: 4px; |  | ||||||
|       border: 1px solid rgba(216, 224, 232, 1); |  | ||||||
|       box-sizing: border-box; |  | ||||||
|       padding: 16px 16px 16px 50px; |  | ||||||
|       margin-top: 8px; |  | ||||||
|       cursor: pointer; |  | ||||||
|       position: relative; |  | ||||||
|       overflow: hidden; |  | ||||||
|  |  | ||||||
|       p { |  | ||||||
|         width: 100%; |  | ||||||
|         height: 25px; |  | ||||||
|         display: flex; |  | ||||||
|         justify-content: space-between; |  | ||||||
|         align-items: center; |  | ||||||
|  |  | ||||||
|         .conference_title { |  | ||||||
|           color: rgba(51, 51, 51, 1); |  | ||||||
|           font-size: 16px; |  | ||||||
|           font-weight: bold; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         .time { |  | ||||||
|           font-size: 14px; |  | ||||||
|           color: #2266FF; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         .unit { |  | ||||||
|           font-size: 14px; |  | ||||||
|           width: 50%; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       h5 { |  | ||||||
|         width: 100px; |  | ||||||
|         height: 20px; |  | ||||||
|         line-height: 20px; |  | ||||||
|         text-align: center; |  | ||||||
|         position: absolute; |  | ||||||
|         left: -22px; |  | ||||||
|         top: 10px; |  | ||||||
|         box-sizing: border-box; |  | ||||||
|         padding-right: 8px; |  | ||||||
|         font-size: 12px; |  | ||||||
|         transform: rotate(-45deg); |  | ||||||
|         background: #FFF3E8; |  | ||||||
|         color: rgba(255, 136, 34, 1); |  | ||||||
|         box-shadow: -1px 1px 0px 0px rgba(216, 224, 232, 1), 1px -1px 0px 0px rgba(216, 224, 232, 1); |  | ||||||
|         margin: 0; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .color0 { |  | ||||||
|         color: #2244FF; |  | ||||||
|         background: #EFF6FF; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .color1 { |  | ||||||
|         background: #FFF3E8; |  | ||||||
|         color: rgba(255, 136, 34, 1); |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .color2 { |  | ||||||
|         background: #EFF6FF; |  | ||||||
|         color: #2266FF; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .color3 { |  | ||||||
|         background-color: #D8E0E8; |  | ||||||
|         color: #999999; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .color4 { |  | ||||||
|         color: #2EA222; |  | ||||||
|         background-color: #D8E0E8; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .svg { |  | ||||||
|         width: 88px; |  | ||||||
|         height: 88px; |  | ||||||
|         position: absolute; |  | ||||||
|         right: -20px; |  | ||||||
|         bottom: -20px; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,186 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <section class="AppCorporateSeal"> |  | ||||||
|       <ai-list v-if="showList"> |  | ||||||
|         <template slot="title"> |  | ||||||
|           <ai-title title="企业印章" :isShowBottomBorder="true"></ai-title> |  | ||||||
|         </template> |  | ||||||
|         <template slot="content"> |  | ||||||
|           <div class="signaturePane"> |  | ||||||
|             <div class="signatureCard" v-for="(op,i) in signatures" :key="i"> |  | ||||||
|               <div class="default" v-if="op.isDefault==1">默认</div> |  | ||||||
|               <div class="body"> |  | ||||||
|                 <el-image :src="`data:image/png;base64,${op.signSealData}`"/> |  | ||||||
|               </div> |  | ||||||
|               <div class="footer"> |  | ||||||
|                 <el-button type="text" :disabled="op.isDefault==1" @click.stop="handleSetDefault(op.id)">设为默认</el-button> |  | ||||||
|                 <hr/> |  | ||||||
|                 <el-button type="text" :disabled="op.isDefault==1||op.signType==1" @click.stop="handleDelete(op.id)">删除 |  | ||||||
|                 </el-button> |  | ||||||
|               </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="signatureCard add" @click="showList=false"> |  | ||||||
|               <ai-icon icon="iconAdd" size="32px"/> |  | ||||||
|               <span>点击添加印章</span> |  | ||||||
|             </div> |  | ||||||
|           </div> |  | ||||||
|         </template> |  | ||||||
|       </ai-list> |  | ||||||
|     <seal-detail v-else/> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   import SealDetail from "./sealDetail"; |  | ||||||
|  |  | ||||||
|   export default { |  | ||||||
|     name: "AppCorporateSeal", |  | ||||||
|     label: "企业印章", |  | ||||||
|     components: {SealDetail}, |  | ||||||
|     provide() { |  | ||||||
|       return { |  | ||||||
|         seal: this |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object, |  | ||||||
|       permissions: Function |  | ||||||
|     }, |  | ||||||
|     data() { |  | ||||||
|       return { |  | ||||||
|         signatures: [], |  | ||||||
|         showList: true |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     created() { |  | ||||||
|       this.getSignatures() |  | ||||||
|     }, |  | ||||||
|     methods: { |  | ||||||
|       getSignatures() { |  | ||||||
|         this.instance.post("/app/syssignaccount/list", null, { |  | ||||||
|           params: { |  | ||||||
|             signType: 2, |  | ||||||
|             size: 999 |  | ||||||
|           } |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res?.data) { |  | ||||||
|             this.signatures = res.data.records |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|       handleSetDefault(id) { |  | ||||||
|         this.$confirm("是否设置该印章为默认印章?").then(() => { |  | ||||||
|           this.instance.post("/app/syssignaccount/default", null, {params: {id, listType: 1}}).then(res => { |  | ||||||
|             if (res?.code == 0) { |  | ||||||
|               this.$message.success("设置成功!") |  | ||||||
|               this.getSignatures() |  | ||||||
|             } |  | ||||||
|           }).catch(() => 0) |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|       handleDelete(ids) { |  | ||||||
|         this.$confirm("是否删除该印章?").then(() => { |  | ||||||
|           this.instance.post("/app/syssignaccount/delete", null, {params: {ids}}).then(res => { |  | ||||||
|             if (res?.code == 0) { |  | ||||||
|               this.$message.success("删除成功!") |  | ||||||
|               this.getSignatures() |  | ||||||
|             } |  | ||||||
|           }).catch(() => 0) |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
|   .AppCorporateSeal { |  | ||||||
|     height: 100%; |  | ||||||
|     background: #f3f6f9; |  | ||||||
|  |  | ||||||
|     :deep( .signaturePane ){ |  | ||||||
|       display: flex; |  | ||||||
|       gap: 16px; |  | ||||||
|       flex-wrap: wrap; |  | ||||||
|       padding: 16px; |  | ||||||
|  |  | ||||||
|       .signatureCard { |  | ||||||
|         width: 290px; |  | ||||||
|         height: 258px; |  | ||||||
|         background: #FFFFFF; |  | ||||||
|         border-radius: 4px; |  | ||||||
|         position: relative; |  | ||||||
|         display: flex; |  | ||||||
|         flex-direction: column; |  | ||||||
|         overflow: hidden; |  | ||||||
|  |  | ||||||
|         &.add { |  | ||||||
|           justify-content: center; |  | ||||||
|           align-items: center; |  | ||||||
|           color: #666666; |  | ||||||
|           cursor: pointer; |  | ||||||
|  |  | ||||||
|           .AiIcon { |  | ||||||
|             width: 32px; |  | ||||||
|             height: 32px; |  | ||||||
|             font-size: 32px; |  | ||||||
|           } |  | ||||||
|  |  | ||||||
|           & > span { |  | ||||||
|             font-size: 12px; |  | ||||||
|             line-height: 16px; |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         .default { |  | ||||||
|           position: absolute; |  | ||||||
|           width: 56px; |  | ||||||
|           height: 24px; |  | ||||||
|           background: #3573FF; |  | ||||||
|           border-radius: 0 0 4px 0; |  | ||||||
|           top: 0; |  | ||||||
|           left: 0; |  | ||||||
|           text-align: center; |  | ||||||
|           line-height: 24px; |  | ||||||
|           font-size: 12px; |  | ||||||
|           color: #FFF; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         .body { |  | ||||||
|           min-height: 0; |  | ||||||
|           flex: 1; |  | ||||||
|           display: flex; |  | ||||||
|           justify-content: center; |  | ||||||
|           align-items: center; |  | ||||||
|           padding: 50px; |  | ||||||
|           cursor: pointer; |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         .footer { |  | ||||||
|           flex-shrink: 0; |  | ||||||
|           height: 40px; |  | ||||||
|           background: rgba(#30426F, .5); |  | ||||||
|           display: flex; |  | ||||||
|           align-items: center; |  | ||||||
|           padding: 8px 0; |  | ||||||
|           box-sizing: border-box; |  | ||||||
|  |  | ||||||
|           hr { |  | ||||||
|             height: 100%; |  | ||||||
|             border-color: rgba(#fff, .5); |  | ||||||
|           } |  | ||||||
|  |  | ||||||
|           & > .el-button { |  | ||||||
|             flex: 1; |  | ||||||
|             color: #fff; |  | ||||||
|  |  | ||||||
|             &[disabled] { |  | ||||||
|               color: rgba(#fff, .5); |  | ||||||
|             } |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| </style> |  | ||||||
| @@ -1,235 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <section class="sealDetail"> |  | ||||||
|     <ai-detail> |  | ||||||
|       <template #title> |  | ||||||
|         <ai-title title="添加企业印章" isShowBack isShowBottomBorder @onBackClick="back"/> |  | ||||||
|       </template> |  | ||||||
|       <template #content> |  | ||||||
|         <el-form size="small" ref="SealForm" :model="form" :rules="rules" label-suffix=":" label-width="160px"> |  | ||||||
|           <ai-title title="单位信息" isShowBottomBorder/> |  | ||||||
|           <el-form-item label="单位名称" prop="organizeName"> |  | ||||||
|             <el-input clearable v-model="form.organizeName" placeholder="请输入..." maxlength="25" show-word-limit/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="单位类型" prop="organizeType"> |  | ||||||
|             <el-select clearable v-model="form.organizeType" placeholder="请输入..."> |  | ||||||
|               <el-option v-for="(op,i) in $dict.getDict('organizeType')" :key="i" :value="op.dictValue" |  | ||||||
|                          :label="op.dictName"/> |  | ||||||
|             </el-select> |  | ||||||
|           </el-form-item> |  | ||||||
|           <div class="flexFillRow"> |  | ||||||
|             <el-form-item label="企业注册类型" prop="organRegType"> |  | ||||||
|               <el-select clearable v-model="form.organRegType" placeholder="请输入..."> |  | ||||||
|                 <el-option v-for="(op,i) in $dict.getDict('organRegType')" :key="i" :value="op.dictValue" |  | ||||||
|                            :label="op.dictName"/> |  | ||||||
|               </el-select> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item v-if="!!form.organRegType" :label="$dict.getLabel('organRegType',form.organRegType)" |  | ||||||
|                           prop="organCode"> |  | ||||||
|               <el-input clearable v-model="form.organCode" placeholder="请输入..."/> |  | ||||||
|             </el-form-item> |  | ||||||
|             <div v-else/> |  | ||||||
|           </div> |  | ||||||
|           <div class="flexFillRow"> |  | ||||||
|             <el-form-item label="注册类型" prop="registerType"> |  | ||||||
|               <el-select clearable v-model="form.registerType" placeholder="请输入..."> |  | ||||||
|                 <el-option v-for="(op,i) in $dict.getDict('registerType')" :key="i" :value="op.dictValue" |  | ||||||
|                            :label="op.dictName"/> |  | ||||||
|               </el-select> |  | ||||||
|             </el-form-item> |  | ||||||
|             <div/> |  | ||||||
|           </div> |  | ||||||
|           <template v-if="form.registerType==1"> |  | ||||||
|             <div class="flexFillRow"> |  | ||||||
|               <el-form-item label="代理人姓名" prop="agentName"> |  | ||||||
|                 <el-input clearable v-model="form.agentName" placeholder="请输入..."/> |  | ||||||
|               </el-form-item> |  | ||||||
|               <el-form-item label="代理人身份证号" prop="agentIdNumber"> |  | ||||||
|                 <el-input clearable v-model="form.agentIdNumber" placeholder="请输入..."/> |  | ||||||
|               </el-form-item> |  | ||||||
|             </div> |  | ||||||
|             <div class="flexFillRow"> |  | ||||||
|               <el-form-item label="代理人手机号" prop="signPhone"> |  | ||||||
|                 <el-input clearable v-model="form.signPhone" placeholder="请输入..."/> |  | ||||||
|               </el-form-item> |  | ||||||
|               <div/> |  | ||||||
|             </div> |  | ||||||
|           </template> |  | ||||||
|           <template v-if="form.registerType==2"> |  | ||||||
|             <div class="flexFillRow"> |  | ||||||
|               <el-form-item label="法人姓名" prop="legalName"> |  | ||||||
|                 <el-input clearable v-model="form.legalName" placeholder="请输入..."/> |  | ||||||
|               </el-form-item> |  | ||||||
|               <el-form-item label="法人身份证号" prop="legalIdNumber"> |  | ||||||
|                 <el-input clearable v-model="form.legalIdNumber" placeholder="请输入..."/> |  | ||||||
|               </el-form-item> |  | ||||||
|             </div> |  | ||||||
|             <div class="flexFillRow"> |  | ||||||
|               <el-form-item label="法人手机号" prop="signPhone"> |  | ||||||
|                 <el-input clearable v-model="form.signPhone" placeholder="请输入..."/> |  | ||||||
|               </el-form-item> |  | ||||||
|               <div/> |  | ||||||
|             </div> |  | ||||||
|           </template> |  | ||||||
|           <ai-title title="印章信息" isShowBottomBorder/> |  | ||||||
|           <el-form-item class="sealImageTypes" label="生成印章类型" prop="organizeTemplateType"> |  | ||||||
|             <div v-for="(op,i) in sealImageTypes" :key="i" class="item" @click="form.organizeTemplateType=op.value"> |  | ||||||
|               <el-image :src="op.image" fit="contain"/> |  | ||||||
|               <el-radio :label="op.value" v-model="form.organizeTemplateType">{{ op.name }}</el-radio> |  | ||||||
|             </div> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="横向文内容" prop="htext"> |  | ||||||
|             <el-input clearable v-model="form.htext" placeholder="0-8个字,如合同专用章,财务专用章等" maxlength="8" show-word-limit/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="下弦文内容" prop="qtext"> |  | ||||||
|             <el-input clearable v-model="form.qtext" placeholder="0-20个字,下弦文是指的贵司公章底部一串防伪数字" maxlength="20" |  | ||||||
|                       show-word-limit/> |  | ||||||
|           </el-form-item> |  | ||||||
|         </el-form> |  | ||||||
|       </template> |  | ||||||
|       <template #footer> |  | ||||||
|         <el-button @click="back">取消</el-button> |  | ||||||
|         <el-button type="primary" @click="handleSubmit" v-loading="loading">提交</el-button> |  | ||||||
|       </template> |  | ||||||
|     </ai-detail> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| import {ID} from "dui/lib/js/utils"; |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "sealDetail", |  | ||||||
|   inject: ['seal'], |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       form: { |  | ||||||
|         organizeTemplateType: "STAR", |  | ||||||
|         organizeType: "4", |  | ||||||
|         organRegType: "NORMAL", |  | ||||||
|         registerType: "1" |  | ||||||
|       }, |  | ||||||
|       loading: false |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     sealImageTypes() { |  | ||||||
|       return this.$dict.getDict("organizeTemplateType")?.map(e => ({ |  | ||||||
|         image: e.dictColor, |  | ||||||
|         value: e.dictValue, |  | ||||||
|         name: e.dictName |  | ||||||
|       })) || [] |  | ||||||
|     }, |  | ||||||
|     rules() { |  | ||||||
|       return { |  | ||||||
|         organizeName: [{required: true, message: "请填写单位名称"}], |  | ||||||
|         organCode: [{required: true, message: `请填写${this.$dict.getLabel('organRegType', this.form.organRegType)}`}], |  | ||||||
|         legalName: [{required: true, message: "请填写法人姓名"}], |  | ||||||
|         agentName: [{required: true, message: "请填写代理人姓名"}], |  | ||||||
|         organizeTemplateType: [{required: true}], |  | ||||||
|         htext: [{required: true, message: "请填写横向文内容"}], |  | ||||||
|         qtext: [{required: true, message: "请填写下弦文内容"}], |  | ||||||
|         organizeType: [{required: true, message: "请选择单位类型"}], |  | ||||||
|         organRegType: [{required: true, message: "请选择企业注册类型"}], |  | ||||||
|         registerType: [{required: true, message: "请选择注册类型"}], |  | ||||||
|         signPhone: [ |  | ||||||
|           {required: true, message: "请填写手机号码"}, |  | ||||||
|           {pattern: /^1[3456789]\d{9}$/, message: "手机号码格式有误"} |  | ||||||
|         ], |  | ||||||
|         legalIdNumber: [ |  | ||||||
|           {required: true, message: "请填写法人身份证号码"}, |  | ||||||
|           {validator: (r, v, cb) => cb(ID.check(v) ? undefined : "身份证号码格式有误")} |  | ||||||
|         ], |  | ||||||
|         agentIdNumber: [ |  | ||||||
|           {required: true, message: "请填写代理人身份证号码"}, |  | ||||||
|           {validator: (r, v, cb) => cb(ID.check(v) ? undefined : "身份证号码格式有误")} |  | ||||||
|         ], |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.$dict.load("registerType", "organRegType", "organizeType", "organizeTemplateType") |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     back() { |  | ||||||
|       this.seal.showList = true |  | ||||||
|       this.seal.getSignatures() |  | ||||||
|     }, |  | ||||||
|     handleSubmit() { |  | ||||||
|       this.$refs.SealForm.validate(v => { |  | ||||||
|         if (v) { |  | ||||||
|           this.loading = true |  | ||||||
|           this.seal.instance.post("/app/syssignaccount/register", { |  | ||||||
|             userType: 0, |  | ||||||
|             signType: 2, |  | ||||||
|             signPhone: this.form.signPhone, |  | ||||||
|             registerInfo: {...this.form, legalArea: 0}, |  | ||||||
|             style: {...this.form, sealColor: "RED"} |  | ||||||
|           }).then(res => { |  | ||||||
|             this.loading = false |  | ||||||
|             if (res?.code == 0) { |  | ||||||
|               this.$message.success("添加成功!") |  | ||||||
|               this.back() |  | ||||||
|             } |  | ||||||
|           }).catch(() => this.loading = false) |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
| .sealDetail { |  | ||||||
|   height: inherit; |  | ||||||
|  |  | ||||||
|   :deep( .ai-detail__content--wrapper ){ |  | ||||||
|     .el-form { |  | ||||||
|       display: flex; |  | ||||||
|       flex-direction: column; |  | ||||||
|       gap: 24px; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .el-form-item { |  | ||||||
|       margin-bottom: 0; |  | ||||||
|  |  | ||||||
|       .el-select { |  | ||||||
|         width: 100%; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       &.sealImageTypes > .el-form-item__content { |  | ||||||
|         display: flex; |  | ||||||
|         gap: 40px; |  | ||||||
|  |  | ||||||
|         .item { |  | ||||||
|           display: flex; |  | ||||||
|           flex-direction: column; |  | ||||||
|           align-items: center; |  | ||||||
|           justify-content: center; |  | ||||||
|           gap: 8px; |  | ||||||
|           cursor: pointer; |  | ||||||
|  |  | ||||||
|           .el-image { |  | ||||||
|             width: 80px; |  | ||||||
|             height: 80px; |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .flexFillRow { |  | ||||||
|       display: flex; |  | ||||||
|       align-items: center; |  | ||||||
|  |  | ||||||
|       & > * { |  | ||||||
|         flex: 1; |  | ||||||
|         min-width: 0; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   :deep( .ai-detail__footer > .el-button ){ |  | ||||||
|     width: 92px; |  | ||||||
|     height: 32px; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,365 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <section class="personal-signature"> |  | ||||||
|     <ai-list v-if="!showPhonePage"> |  | ||||||
|       <ai-title slot="title" title="个人签名" :isShowBottomBorder="false"/> |  | ||||||
|       <template #custom> |  | ||||||
|         <div class="signaturePane"> |  | ||||||
|           <div class="signatureCard" v-for="(op,i) in signatures" :key="i"> |  | ||||||
|             <div class="default" v-if="op.isDefault==1">默认</div> |  | ||||||
|             <div class="body"> |  | ||||||
|               <el-image :src="`data:image/png;base64,${op.signSealData}`"/> |  | ||||||
|             </div> |  | ||||||
|             <div class="footer"> |  | ||||||
|               <el-button type="text" :disabled="op.isDefault==1" @click.stop="handleSetDefault(op.id)">设为默认</el-button> |  | ||||||
|               <hr/> |  | ||||||
|               <el-button type="text" :disabled="op.isDefault==1||op.signType>0" @click.stop="handleDelete(op.id)">删除 |  | ||||||
|               </el-button> |  | ||||||
|             </div> |  | ||||||
|           </div> |  | ||||||
|           <div class="signatureCard add" @click="dialog=true"> |  | ||||||
|             <ai-icon icon="iconAdd" size="32px"/> |  | ||||||
|             <span>点击添加签名</span> |  | ||||||
|           </div> |  | ||||||
|         </div> |  | ||||||
|       </template> |  | ||||||
|     </ai-list> |  | ||||||
|     <ai-dialog :visible.sync="dialog" v-bind="dialogConf" @onConfirm="handleSubmit" |  | ||||||
|                @closed="form={},drawPlaceholder=true,qrCode=null,showQRCode=false,getSignatures()"> |  | ||||||
|       <ai-drawer v-if="hasAuthed" :seal.sync="sealData" ref="aiDrawer"> |  | ||||||
|         <template #tools> |  | ||||||
|           <el-popover trigger="manual" v-model="showQRCode"> |  | ||||||
|             <el-image :src="qrCode"/> |  | ||||||
|             <div class="writeInPhone" slot="reference" @click.stop="showQR"> |  | ||||||
|               <ai-icon icon="iconEwm"/> |  | ||||||
|               <span>手机签名</span> |  | ||||||
|             </div> |  | ||||||
|           </el-popover> |  | ||||||
|         </template> |  | ||||||
|       </ai-drawer> |  | ||||||
|       <el-form size="small" :model="form" ref="authForm" :rules="rules" class="authZone" v-else label-suffix=":" |  | ||||||
|                label-width="100px"> |  | ||||||
|         <el-alert type="warning" title="第一次添加个人签名,需先进行实名认证" show-icon :closable="false"/> |  | ||||||
|         <el-form-item label="姓名" prop="personName"> |  | ||||||
|           <el-input v-model="form.personName" clearable placeholder="姓名"/> |  | ||||||
|         </el-form-item> |  | ||||||
|         <el-form-item label="身份证号" prop="idNumber"> |  | ||||||
|           <el-input v-model="form.idNumber" clearable placeholder="身份证号"/> |  | ||||||
|         </el-form-item> |  | ||||||
|         <el-form-item label="手机号码" prop="signPhone"> |  | ||||||
|           <el-input v-model="form.signPhone" clearable placeholder="手机号码"/> |  | ||||||
|         </el-form-item> |  | ||||||
|       </el-form> |  | ||||||
|     </ai-dialog> |  | ||||||
|     <draw-in-phone v-if="showPhonePage"/> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| import {mapState} from "vuex"; |  | ||||||
| import DrawInPhone from "./drawInPhone"; |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "AppPersonalSignature", |  | ||||||
|   label: "个人签名", |  | ||||||
|   components: {DrawInPhone}, |  | ||||||
|   provide() { |  | ||||||
|     return { |  | ||||||
|       signature: this |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     ...mapState(['user']), |  | ||||||
|     hasAuthed() { |  | ||||||
|       return this.signatures.length > 0 |  | ||||||
|     }, |  | ||||||
|     dialogConf() { |  | ||||||
|       return this.hasAuthed ? { |  | ||||||
|         title: "手写签名", |  | ||||||
|         width: '720px' |  | ||||||
|       } : { |  | ||||||
|         title: "实名认证", |  | ||||||
|         width: '520px' |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     rules() { |  | ||||||
|       return { |  | ||||||
|         personName: [{required: true, message: "请填写姓名"}], |  | ||||||
|         signPhone: [ |  | ||||||
|           {required: true, message: "请填写手机号码"}, |  | ||||||
|           {pattern: /^1[3456789]\d{9}$/, message: "手机号码格式有误"} |  | ||||||
|         ], |  | ||||||
|         idNumber: [ |  | ||||||
|           {required: true, message: "请填写身份证号码"}, |  | ||||||
|           {validator: (r, v, cb) => cb(ID.check(v) ? undefined : "身份证号码格式有误")} |  | ||||||
|         ], |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       signatures: [], |  | ||||||
|       dialog: false, |  | ||||||
|       form: {}, |  | ||||||
|       sealData: null, |  | ||||||
|       qrCode: null, |  | ||||||
|       showQRCode: false, |  | ||||||
|       showPhonePage: false, |  | ||||||
|       loading: false, |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     if (this.$route.query.userId && this.$route.hash == "#phone") { |  | ||||||
|       this.showPhonePage = true |  | ||||||
|     } else { |  | ||||||
|       this.getSignatures() |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     getSignatures() { |  | ||||||
|       this.instance.post("/app/syssignaccount/list", null, { |  | ||||||
|         params: { |  | ||||||
|           size: 999 |  | ||||||
|         } |  | ||||||
|       }).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           this.signatures = res.data.records |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     handleSubmit() { |  | ||||||
|       if (this.loading) return |  | ||||||
|       if (this.hasAuthed && this.$refs['aiDrawer'].drawPlaceholder) return this.$message.error("请签名") |  | ||||||
|       this.loading = true |  | ||||||
|       if (this.hasAuthed) { |  | ||||||
|         let sealData = this.sealData?.replace(/data:image\/png;base64,/, '') |  | ||||||
|         sealData && this.instance({ |  | ||||||
|           url: '/app/syssignaccount/upload-sealdata', |  | ||||||
|           headers: {"Content-Type": "application/json"}, |  | ||||||
|           method: 'post', |  | ||||||
|           params: {userId: this.user.info.id}, |  | ||||||
|           data: sealData |  | ||||||
|         }).then(res => { |  | ||||||
|           this.loading = false |  | ||||||
|           if (res?.code == 0) { |  | ||||||
|             this.dialog = false |  | ||||||
|             this.$message.success("添加成功!") |  | ||||||
|             this.getSignatures() |  | ||||||
|           } |  | ||||||
|         }).catch(() => { |  | ||||||
|           this.loading = false |  | ||||||
|         }) |  | ||||||
|       } else { |  | ||||||
|         this.$refs.authForm.validate(v => { |  | ||||||
|           if (v) { |  | ||||||
|             this.instance.post("/app/syssignaccount/register", { |  | ||||||
|               signPhone: this.form.signPhone, |  | ||||||
|               signType: 1, |  | ||||||
|               userType: 0, |  | ||||||
|               registerInfo: {...this.form}, |  | ||||||
|               style: {personTemplateType: 'RECTANGLE', sealColor: 'RED'} |  | ||||||
|             }).then(res => { |  | ||||||
|               this.loading = false |  | ||||||
|               if (res?.code == 0) { |  | ||||||
|                 this.dialog = false |  | ||||||
|                 this.$message.success("认证成功!") |  | ||||||
|                 this.getSignatures() |  | ||||||
|               } |  | ||||||
|             }).catch(() => { |  | ||||||
|               this.loading = false |  | ||||||
|             }) |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     handleSetDefault(id) { |  | ||||||
|       this.$confirm("是否设置该签名为默认签名?").then(() => { |  | ||||||
|         this.instance.post("/app/syssignaccount/default", null, {params: {id, listType: 0}}).then(res => { |  | ||||||
|           if (res?.code == 0) { |  | ||||||
|             this.$message.success("设置成功!") |  | ||||||
|             this.getSignatures() |  | ||||||
|           } |  | ||||||
|         }).catch(() => 0) |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     handleDelete(ids) { |  | ||||||
|       this.$confirm("是否删除该签名?").then(() => { |  | ||||||
|         this.instance.post("/app/syssignaccount/delete", null, {params: {ids}}).then(res => { |  | ||||||
|           if (res?.code == 0) { |  | ||||||
|             this.$message.success("删除成功!") |  | ||||||
|             this.getSignatures() |  | ||||||
|           } |  | ||||||
|         }).catch(() => 0) |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     showQR() { |  | ||||||
|       if (!this.qrCode) { |  | ||||||
|         let url = `${location.href}?userId=${this.user.info.id}#phone` |  | ||||||
|         this.instance.post("/app/syssignaccount/draw-qrcode", null, { |  | ||||||
|           params: {url} |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res?.data) { |  | ||||||
|             this.showQRCode = true |  | ||||||
|             this.qrCode = res.data |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       } else { |  | ||||||
|         this.showQRCode = !this.showQRCode |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
| .personal-signature { |  | ||||||
|   height: 100%; |  | ||||||
|   background: #f3f6f9; |  | ||||||
|   overflow: auto; |  | ||||||
|  |  | ||||||
|   :deep( .signaturePane ){ |  | ||||||
|     display: flex; |  | ||||||
|     gap: 16px; |  | ||||||
|     flex-wrap: wrap; |  | ||||||
|     padding: 16px; |  | ||||||
|  |  | ||||||
|     .signatureCard { |  | ||||||
|       width: 290px; |  | ||||||
|       height: 258px; |  | ||||||
|       background: #FFFFFF; |  | ||||||
|       border-radius: 4px; |  | ||||||
|       position: relative; |  | ||||||
|       display: flex; |  | ||||||
|       flex-direction: column; |  | ||||||
|       overflow: hidden; |  | ||||||
|  |  | ||||||
|       &.add { |  | ||||||
|         justify-content: center; |  | ||||||
|         align-items: center; |  | ||||||
|         color: #666666; |  | ||||||
|         cursor: pointer; |  | ||||||
|  |  | ||||||
|         .AiIcon { |  | ||||||
|           width: 32px; |  | ||||||
|           height: 32px; |  | ||||||
|           font-size: 32px; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         & > span { |  | ||||||
|           font-size: 12px; |  | ||||||
|           line-height: 16px; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .default { |  | ||||||
|         position: absolute; |  | ||||||
|         width: 56px; |  | ||||||
|         height: 24px; |  | ||||||
|         background: #3573FF; |  | ||||||
|         border-radius: 0 0 4px 0; |  | ||||||
|         top: 0; |  | ||||||
|         left: 0; |  | ||||||
|         text-align: center; |  | ||||||
|         line-height: 24px; |  | ||||||
|         font-size: 12px; |  | ||||||
|         color: #FFF; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .body { |  | ||||||
|         min-height: 0; |  | ||||||
|         flex: 1; |  | ||||||
|         display: flex; |  | ||||||
|         justify-content: center; |  | ||||||
|         align-items: center; |  | ||||||
|         padding: 25px; |  | ||||||
|         pointer-events: none; |  | ||||||
|  |  | ||||||
|         .el-image { |  | ||||||
|           width: 100%; |  | ||||||
|           height: 100% |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .footer { |  | ||||||
|         flex-shrink: 0; |  | ||||||
|         height: 40px; |  | ||||||
|         background: rgba(#30426F, .5); |  | ||||||
|         display: flex; |  | ||||||
|         align-items: center; |  | ||||||
|         padding: 8px 0; |  | ||||||
|         box-sizing: border-box; |  | ||||||
|  |  | ||||||
|         hr { |  | ||||||
|           height: 100%; |  | ||||||
|           border-color: rgba(#fff, .5); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         & > .el-button { |  | ||||||
|           flex: 1; |  | ||||||
|           color: #fff; |  | ||||||
|  |  | ||||||
|           &[disabled] { |  | ||||||
|             color: rgba(#fff, .5); |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   :deep( .writeInPhone ){ |  | ||||||
|     position: absolute; |  | ||||||
|     width: 100px; |  | ||||||
|     height: 32px; |  | ||||||
|     background: rgba(#000, .5); |  | ||||||
|     border-radius: 16px; |  | ||||||
|     display: flex; |  | ||||||
|     align-items: center; |  | ||||||
|     justify-content: center; |  | ||||||
|     gap: 4px; |  | ||||||
|     color: rgba(#fff, .6); |  | ||||||
|     cursor: pointer; |  | ||||||
|     left: 16px; |  | ||||||
|     top: 16px; |  | ||||||
|  |  | ||||||
|     .AiIcon { |  | ||||||
|       width: auto; |  | ||||||
|       height: auto; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     &:hover { |  | ||||||
|       color: #fff; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   :deep( .ai-dialog__wrapper ){ |  | ||||||
|     .ai-dialog__content--wrapper { |  | ||||||
|       padding-right: 0 !important; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .el-dialog__body { |  | ||||||
|       padding: 24px 0; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     .authZone { |  | ||||||
|       padding: 0 16px 24px; |  | ||||||
|       width: 100%; |  | ||||||
|       box-sizing: border-box; |  | ||||||
|       display: flex; |  | ||||||
|       flex-direction: column; |  | ||||||
|       gap: 24px; |  | ||||||
|  |  | ||||||
|       .el-alert { |  | ||||||
|         border: 1px solid #FF8822; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .el-form-item { |  | ||||||
|         margin-bottom: 0; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,110 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <section class="drawInPhone" @touchmove.prevent> |  | ||||||
|     <div class="endPage" v-if="finished">操作结束请关闭页面</div> |  | ||||||
|     <ai-drawer :seal.sync="sealData" placeholder="请签名" :width="device.width" :height="device.height"> |  | ||||||
|       <template #tools> |  | ||||||
|         <div class="writeInPhone" slot="reference" @click.stop="handleSubmit"> |  | ||||||
|           <ai-icon icon="iconPublish"/> |  | ||||||
|           <span>提交</span> |  | ||||||
|         </div> |  | ||||||
|       </template> |  | ||||||
|     </ai-drawer> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| export default { |  | ||||||
|   name: "drawInPhone", |  | ||||||
|   inject: ['signature'], |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       sealData: null, |  | ||||||
|       device: {width: 0, height: 0}, |  | ||||||
|       finished: false |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.device.width = document.body.clientWidth |  | ||||||
|     this.device.height = document.body.clientHeight |  | ||||||
|     window.onresize = () => { |  | ||||||
|       this.device.width = document.body.clientWidth |  | ||||||
|       this.device.height = document.body.clientHeight |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     handleSubmit() { |  | ||||||
|       let sealData = this.sealData?.replace(/data:image\/png;base64,/, ''), |  | ||||||
|           {userId} = this.$route.query |  | ||||||
|       if (!userId) return alert("缺少必要参数") |  | ||||||
|       sealData && this.signature.instance({ |  | ||||||
|         url: '/app/syssignaccount/upload-sealdata', |  | ||||||
|         headers: {"Content-Type": "application/json"}, |  | ||||||
|         method: 'post', |  | ||||||
|         params: {userId}, |  | ||||||
|         data: sealData, |  | ||||||
|         withoutToken: true |  | ||||||
|       }).then(res => { |  | ||||||
|         if (res?.code == 0) { |  | ||||||
|           alert("添加成功!") |  | ||||||
|           this.finished = true |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
| .drawInPhone { |  | ||||||
|   position: fixed; |  | ||||||
|   left: 0; |  | ||||||
|   right: 0; |  | ||||||
|   top: 0; |  | ||||||
|   bottom: 0; |  | ||||||
|   z-index: 20210205932; |  | ||||||
|  |  | ||||||
|   .endPage { |  | ||||||
|     position: fixed; |  | ||||||
|     left: 0; |  | ||||||
|     right: 0; |  | ||||||
|     top: 0; |  | ||||||
|     bottom: 0; |  | ||||||
|     z-index: 20210205933; |  | ||||||
|     background: rgba(#000, .8); |  | ||||||
|     color: #999; |  | ||||||
|     display: flex; |  | ||||||
|     justify-content: center; |  | ||||||
|     align-items: center; |  | ||||||
|     font-size: 32px; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .AiDrawer { |  | ||||||
|     margin: 0; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .writeInPhone { |  | ||||||
|     position: absolute; |  | ||||||
|     width: 72px; |  | ||||||
|     height: 32px; |  | ||||||
|     background: rgba(#000, .5); |  | ||||||
|     border-radius: 16px; |  | ||||||
|     display: flex; |  | ||||||
|     align-items: center; |  | ||||||
|     justify-content: center; |  | ||||||
|     gap: 4px; |  | ||||||
|     color: rgba(#fff, .6); |  | ||||||
|     cursor: pointer; |  | ||||||
|     left: 16px; |  | ||||||
|     top: 16px; |  | ||||||
|  |  | ||||||
|     .AiIcon { |  | ||||||
|       width: auto; |  | ||||||
|       height: auto; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     &:hover { |  | ||||||
|       color: #fff; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,66 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <div class="doc-circulation ailist-wrapper"> |  | ||||||
|     <keep-alive :include="['List']"> |  | ||||||
|       <component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component> |  | ||||||
|     </keep-alive> |  | ||||||
|   </div> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   import List from './components/List' |  | ||||||
|   import Add from './components/Add' |  | ||||||
|  |  | ||||||
|   export default { |  | ||||||
|     name: 'AppBuddyMessage', |  | ||||||
|     label: '好友欢迎语', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data () { |  | ||||||
|       return { |  | ||||||
|         component: 'List', |  | ||||||
|         params: {}, |  | ||||||
|         include: [] |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     components: { |  | ||||||
|       Add, |  | ||||||
|       List |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     mounted () { |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       onChange (data) { |  | ||||||
|         if (data.type === 'Add') { |  | ||||||
|           this.component = 'Add' |  | ||||||
|           this.params = data.params |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (data.type === 'list') { |  | ||||||
|           this.component = 'List' |  | ||||||
|           this.params = data.params |  | ||||||
|  |  | ||||||
|           this.$nextTick(() => { |  | ||||||
|             if (data.isRefresh) { |  | ||||||
|               this.$refs.component.getList() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss"> |  | ||||||
|   .doc-circulation { |  | ||||||
|     height: 100%; |  | ||||||
|     background: #F3F6F9; |  | ||||||
|     overflow: auto; |  | ||||||
|   } |  | ||||||
| </style> |  | ||||||
| @@ -1,380 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <ai-detail> |  | ||||||
|     <template slot="title"> |  | ||||||
|       <ai-title title="新建欢迎语" isShowBack isShowBottomBorder @onBackClick="cancel(false)"></ai-title> |  | ||||||
|     </template> |  | ||||||
|  |  | ||||||
|     <template slot="content"> |  | ||||||
|       <ai-card> |  | ||||||
|         <template #title> |  | ||||||
|           <div class="ai-card__title"> |  | ||||||
|             <h2>基本信息</h2> |  | ||||||
|             <span>*一个成员如果被设置了多个欢迎语,将会使用最新设置或修改的欢迎语</span> |  | ||||||
|           </div> |  | ||||||
|         </template> |  | ||||||
|  |  | ||||||
|         <template #content> |  | ||||||
|           <el-form class="ai-form" :rules="rules" ref="userForm" :model="form" label-width="100px" label-position="right"> |  | ||||||
|             <el-form-item label="使用成员" prop="users" style="width: 100%"> |  | ||||||
|               <el-input v-model="users" placeholder="请选择使用成员" disabled style="width: 100%"> |  | ||||||
|                 <template #append> |  | ||||||
|                   <ai-user-selecter refs="addTags" :instance="instance" v-model="form.users"> |  | ||||||
|                     <el-button size="small">选择</el-button> |  | ||||||
|                   </ai-user-selecter> |  | ||||||
|                 </template> |  | ||||||
|               </el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|           </el-form> |  | ||||||
|         </template> |  | ||||||
|       </ai-card> |  | ||||||
|  |  | ||||||
|       <ai-card title="发送欢迎语"> |  | ||||||
|         <template #content> |  | ||||||
|           <el-form class="ai-form" ref="form" :model="form" label-width="110px" label-position="right"> |  | ||||||
|             <el-form-item class="el-form-item__textarea" label="文本内容" prop="explain" style="width: 100%"> |  | ||||||
|               <span @click="insertNickname" class="el-form-item__btn" type="text">[插入居民昵称]</span> |  | ||||||
|               <el-input type="textarea" placeholder="请输入…" v-model="form.content" maxlength="1000" :rows="5" show-word-limit></el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="其他类型" prop="explain" style="width: 100%"> |  | ||||||
|               <el-radio-group v-model="form.type" @change="onTypeChange"> |  | ||||||
|                 <el-radio label="image">图片</el-radio> |  | ||||||
|                 <el-radio label="link">链接</el-radio> |  | ||||||
|                 <el-radio label="video">视频</el-radio> |  | ||||||
|                 <el-radio label="miniapp">小程序</el-radio> |  | ||||||
|               </el-radio-group> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="图片" prop="files" style="width: 100%" v-if="form.type === 'image'"> |  | ||||||
|               <ai-uploader :instance="instance" isWechat v-model="form.files" :limit="1" url="/app/wxcp/upload/uploadFile?type=image"></ai-uploader> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="链接" prop="linkUrl" style="width: 100%" v-if="form.type === 'link'"> |  | ||||||
|               <el-input placeholder="链接地址请以http或https开头" :rows="2" type="textarea" v-model="form.linkUrl"></el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="链接图片地址" prop="picUrl" style="width: 100%" v-if="form.type === 'link'"> |  | ||||||
|               <ai-uploader :instance="instance" v-model="form.picUrl" :limit="1"></ai-uploader> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="链接标题" prop="title" style="width: 100%" v-if="form.type === 'link'"> |  | ||||||
|               <el-input placeholder="请输入链接标题" v-model="form.title"></el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="视频" prop="files" style="width: 100%" v-if="form.type === 'video'"> |  | ||||||
|               <ai-uploader :instance="instance" fileType="file" isWechat acceptType=".mp4" v-model="form.files" :limit="1" url="/app/wxcp/upload/uploadFile?type=video"></ai-uploader> |  | ||||||
|             </el-form-item> |  | ||||||
|             <!-- <el-form-item label="小程序" prop="applets" style="width: 100%" v-if="form.type === 'miniapp'"> |  | ||||||
|               <el-radio-group v-model="form.applets"> |  | ||||||
|                 <div class="appletss"> |  | ||||||
|                   <div class="applets-item" @click="form.applets = '0'" :class="[form.applets === '0' ? 'applets-active' : '']"> |  | ||||||
|                     <el-radio label="0"></el-radio> |  | ||||||
|                     <img src="http://www.9665.com/uploadfile/2018/0607/20180607042142312.png"> |  | ||||||
|                     <span>小程序</span> |  | ||||||
|                   </div> |  | ||||||
|                   <div class="applets-item" @click="form.applets = '1'" :class="[form.applets === '1' ? 'applets-active' : '']"> |  | ||||||
|                     <el-radio label="1"></el-radio> |  | ||||||
|                     <img src="http://www.9665.com/uploadfile/2018/0607/20180607042142312.png"> |  | ||||||
|                     <span>小程序</span> |  | ||||||
|                   </div> |  | ||||||
|                   <div class="applets-item" @click="form.applets = '2'" :class="[form.applets === '2' ? 'applets-active' : '']"> |  | ||||||
|                     <el-radio label="2"></el-radio> |  | ||||||
|                     <img src="http://www.9665.com/uploadfile/2018/0607/20180607042142312.png"> |  | ||||||
|                     <span>小程序</span> |  | ||||||
|                   </div> |  | ||||||
|                 </div> |  | ||||||
|               </el-radio-group> |  | ||||||
|             </el-form-item> --> |  | ||||||
|             <el-form-item label="小程序标题" prop="title" style="width: 100%" v-if="form.type === 'miniapp'"> |  | ||||||
|               <el-input placeholder="请输入小程序标题" v-model="form.title"></el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="小程序APPID" prop="appid" style="width: 100%" v-if="form.type === 'miniapp'"> |  | ||||||
|               <el-input placeholder="请输入小程序APPID" v-model="form.appid"></el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="小程序跳转页面" prop="page" style="width: 100%" v-if="form.type === 'miniapp'"> |  | ||||||
|               <el-input placeholder="如pages/home/Home" v-model="form.page"></el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="小程序图片" prop="files" style="width: 100%" v-if="form.type === 'miniapp'"> |  | ||||||
|               <ai-uploader :instance="instance" v-model="form.files" isWechat :limit="1" url="/app/wxcp/upload/uploadFile?type=image"></ai-uploader> |  | ||||||
|             </el-form-item> |  | ||||||
|           </el-form> |  | ||||||
|         </template> |  | ||||||
|       </ai-card> |  | ||||||
|     </template> |  | ||||||
|  |  | ||||||
|     <template #footer> |  | ||||||
|       <el-button @click="cancel">取消</el-button> |  | ||||||
|       <el-button type="primary" @click="confirm">提交</el-button> |  | ||||||
|     </template> |  | ||||||
|   </ai-detail> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   const validateUser = (rule, value, callback) => { |  | ||||||
|     if (!value.length) { |  | ||||||
|       callback(new Error('请选择使用成员')) |  | ||||||
|     } else { |  | ||||||
|       callback() |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   export default { |  | ||||||
|     name: 'Add', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object, |  | ||||||
|       params: Object |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data () { |  | ||||||
|       return { |  | ||||||
|         isShow: false, |  | ||||||
|         info: {}, |  | ||||||
|         form: { |  | ||||||
|           users: [], |  | ||||||
|           appId: '', |  | ||||||
|           page: '', |  | ||||||
|           title: '', |  | ||||||
|           miniappImg: [], |  | ||||||
|           picUrl: [], |  | ||||||
|           content: '', |  | ||||||
|           files: [], |  | ||||||
|           linkUrl: '', |  | ||||||
|           isRemind: true, |  | ||||||
|           type: 'text' |  | ||||||
|         }, |  | ||||||
|         rules: { |  | ||||||
|           users: [ |  | ||||||
|             { required: true, message: '请选择使用成员', trigger: 'change' }, |  | ||||||
|             { validator: validateUser, trigger: 'change' } |  | ||||||
|           ] |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     computed: { |  | ||||||
|       users () { |  | ||||||
|         return this.form.users.map(v => v.name).join(',') |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     created () { |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       getInfo (id) { |  | ||||||
|         this.instance.post(`/app/appleavemessage/queryDetailById?id=${id}`).then(res => { |  | ||||||
|           if (res.code === 0) { |  | ||||||
|             this.info = res.data |  | ||||||
|             this.info.appLeaveMessageReplyList = res.data.appLeaveMessageReplyList.map(item => { |  | ||||||
|               item.images = JSON.parse(item.images).map(item => { |  | ||||||
|                 return { |  | ||||||
|                   ...item, |  | ||||||
|                   url: item.accessUrl |  | ||||||
|                 } |  | ||||||
|               }) |  | ||||||
|  |  | ||||||
|               return item |  | ||||||
|             }) |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       validateUser (rule, value, callback) { |  | ||||||
|         if (!value.length) { |  | ||||||
|           callback(new Error('请选择使用成员')) |  | ||||||
|         } else { |  | ||||||
|           callback() |  | ||||||
|         } |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       onClose () { |  | ||||||
|         this.form.explain = '' |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       onTypeChange () { |  | ||||||
|         this.form.files = [] |  | ||||||
|         this.form.picUrl = [] |  | ||||||
|         this.form.appId = '' |  | ||||||
|         this.form.page = '' |  | ||||||
|         this.form.title = '' |  | ||||||
|         this.form.miniappImg = [] |  | ||||||
|         this.form.linkUrl = '' |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       insertNickname () { |  | ||||||
|         this.form.content = this.form.content + '[用户昵称]' |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       onChange () { |  | ||||||
|  |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       confirm () { |  | ||||||
|         this.$refs.userForm.validate((valid) => { |  | ||||||
|           if (valid) { |  | ||||||
|             if (this.form.type === 'text' && !this.form.content) { |  | ||||||
|               return this.$message.error('请输入消息内容') |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (this.form.type === 'image' && !this.form.files.length) { |  | ||||||
|               return this.$message.error('请上传图片') |  | ||||||
|             } |  | ||||||
|             // if (this.form.type === 'file' && !this.form.files.length) { |  | ||||||
|             //   return this.$message.error('请上传附件') |  | ||||||
|             // } |  | ||||||
|             if (this.form.type === 'video' && !this.form.files.length) { |  | ||||||
|               return this.$message.error('请上传视频') |  | ||||||
|             } |  | ||||||
|             if (this.form.type === 'link' && !this.form.linkUrl) { |  | ||||||
|               return this.$message.error('请输入链接') |  | ||||||
|             } |  | ||||||
|             if (this.form.type === 'link' && !this.form.picUrl.length) { |  | ||||||
|               return this.$message.error('请输入链接图片') |  | ||||||
|             } |  | ||||||
|             if (this.form.type === 'link' && !this.form.title) { |  | ||||||
|               return this.$message.error('请输入链接标题') |  | ||||||
|             } |  | ||||||
|             if (this.form.type === 'miniapp' && !this.form.title) { |  | ||||||
|               return this.$message.error('请输入小程序标题') |  | ||||||
|             } |  | ||||||
|             if (this.form.type === 'miniapp' && !this.form.appid) { |  | ||||||
|               return this.$message.error('请输入小程序appid') |  | ||||||
|             } |  | ||||||
|             if (this.form.type === 'miniapp' && !this.form.page) { |  | ||||||
|               return this.$message.error('请输入小程序page') |  | ||||||
|             } |  | ||||||
|             if (this.form.type === 'miniapp' && !this.form.files.length) { |  | ||||||
|               return this.$message.error('请上传小程序图片') |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             this.instance.post(`/app/wxcp/wxwelcomeword/add`, { |  | ||||||
|               type: '1', |  | ||||||
|               content: this.form.content || '', |  | ||||||
|               isNotify: '0', |  | ||||||
|               media: { |  | ||||||
|                 createdAt: this.form.files.length ? this.form.files[0].media.createdAt : '', |  | ||||||
|                 file: this.form.files.length ? this.form.files[0] : {}, |  | ||||||
|                 mediaId: this.form.files.length ? this.form.files[0].media.mediaId : '', |  | ||||||
|                 sysFileId: this.form.files.length ? this.form.files[0].id : '', |  | ||||||
|                 type: this.form.type, |  | ||||||
|                 linkUrl: this.form.type === 'link' && this.form.linkUrl ? this.form.linkUrl : '', |  | ||||||
|                 title: this.form.title, |  | ||||||
|                 appId: this.form.appid, |  | ||||||
|                 page: this.form.page, |  | ||||||
|                 picUrl: this.form.type === 'link' ? this.form.picUrl[0].url : '' |  | ||||||
|               }, |  | ||||||
|               users: this.form.users.map(item => { |  | ||||||
|                 return { |  | ||||||
|                   type: 0, |  | ||||||
|                   objectId: item.id, |  | ||||||
|                   objectName: item.name |  | ||||||
|                 } |  | ||||||
|               }) |  | ||||||
|             }).then(res => { |  | ||||||
|               if (res.code == 0) { |  | ||||||
|                 this.$message.success('提交成功') |  | ||||||
|                 setTimeout(() => { |  | ||||||
|                   this.cancel(true) |  | ||||||
|                 }, 600) |  | ||||||
|               } |  | ||||||
|             }) |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       cancel (isRefresh) { |  | ||||||
|         this.$emit('change', { |  | ||||||
|           type: 'list', |  | ||||||
|           isRefresh: isRefresh ? true : false |  | ||||||
|         }) |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
|   .ai-card__title { |  | ||||||
|     display: flex; |  | ||||||
|     align-items: center; |  | ||||||
|  |  | ||||||
|     h2 { |  | ||||||
|       margin-right: 20px; |  | ||||||
|       color: #222222; |  | ||||||
|       font-size: 16px; |  | ||||||
|       font-weight: 700; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     span { |  | ||||||
|       color: #888888; |  | ||||||
|       font-size: 14px; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .appletss { |  | ||||||
|     display: flex; |  | ||||||
|     flex-wrap: wrap; |  | ||||||
|  |  | ||||||
|     .applets-item { |  | ||||||
|       display: flex; |  | ||||||
|       align-items: center; |  | ||||||
|       width: 400px; |  | ||||||
|       height: 60px; |  | ||||||
|       margin-right: 8px; |  | ||||||
|       margin-bottom: 8px; |  | ||||||
|       padding: 0 17px; |  | ||||||
|       background: #FFFFFF; |  | ||||||
|       border-radius: 2px; |  | ||||||
|       border: 1px solid #D0D4DC; |  | ||||||
|       cursor: pointer; |  | ||||||
|  |  | ||||||
|       &:hover { |  | ||||||
|         border-color: #2266FF; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       :deep( ){ |  | ||||||
|         .el-radio__label { |  | ||||||
|           display: none; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       img { |  | ||||||
|         width: 40px; |  | ||||||
|         height: 40px; |  | ||||||
|         margin: 0 8px 0 13px; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       span { |  | ||||||
|         color: #222222; |  | ||||||
|         font-size: 12px; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .el-radio { |  | ||||||
|         margin: 0; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       &.applets-active { |  | ||||||
|         border-color: #2266FF; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .tips { |  | ||||||
|     position: relative; |  | ||||||
|     top: 2px; |  | ||||||
|     padding-left: 8px; |  | ||||||
|     color: #222222; |  | ||||||
|     font-size: 14px; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .el-form-item-item__textarea  { |  | ||||||
|     position: relative; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|     .el-form-item__btn { |  | ||||||
|       position: absolute; |  | ||||||
|       bottom: 12px; |  | ||||||
|       left: 12px; |  | ||||||
|       line-height: 1; |  | ||||||
|       z-index: 1; |  | ||||||
|       color: #2266FF; |  | ||||||
|       font-size: 14px; |  | ||||||
|       user-select: none; |  | ||||||
|       background: #fff; |  | ||||||
|       cursor: pointer; |  | ||||||
|     } |  | ||||||
| </style> |  | ||||||
| @@ -1,235 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <ai-list class="message"> |  | ||||||
|     <template slot="title"> |  | ||||||
|       <ai-title title="好友欢迎语" isShowBottomBorder></ai-title> |  | ||||||
|     </template> |  | ||||||
|     <template slot="content"> |  | ||||||
|       <ai-search-bar class="search-bar"> |  | ||||||
|         <template #left> |  | ||||||
|           <el-button size="small" type="primary" icon="iconfont iconAdd" @click="toAdd">添加好友欢迎语</el-button> |  | ||||||
|         </template> |  | ||||||
|         <template slot="right"> |  | ||||||
|         </template> |  | ||||||
|       </ai-search-bar> |  | ||||||
|       <ai-table |  | ||||||
|         :tableData="tableData" |  | ||||||
|         :col-configs="colConfigs" |  | ||||||
|         :total="total" |  | ||||||
|         style="margin-top: 6px;" |  | ||||||
|         :current.sync="search.current" |  | ||||||
|         :size.sync="search.size" |  | ||||||
|         @getList="getList"> |  | ||||||
|         <el-table-column slot="type" width="240px" label="消息内容" align="center"> |  | ||||||
|           <template slot-scope="{ row }"> |  | ||||||
|             <el-popover |  | ||||||
|               placement="bottom" |  | ||||||
|               width="400" |  | ||||||
|               :visible-arrow="false" |  | ||||||
|               popper-class="wechat-message__container" |  | ||||||
|               trigger="hover"> |  | ||||||
|               <div class="count" slot="reference">共{{ row.count }}条</div> |  | ||||||
|               <div class="message-info"> |  | ||||||
|                 <h2 v-if="row.content" :style="{marginBottom: row.media ? '16px' : '0'}">{{ row.content }}</h2> |  | ||||||
|                 <div class="message-info__wrapper" v-if="row.media && (row.media.file || row.media.type === 'link')"> |  | ||||||
|                   <img v-if="row.media.type === 'image' || row.media.type === 'miniapp'" :src="row.media.file.url"> |  | ||||||
|                   <video v-if="row.media.type === 'video'" :src="row.media.file.url"></video> |  | ||||||
|                   <img v-if="row.media.type === 'link'" :src="row.media.picUrl"> |  | ||||||
|                   <div class="message-info__wrapper--right"> |  | ||||||
|                     <h3 v-if="row.media.type === 'miniapp'">{{ row.media.title }}</h3> |  | ||||||
|                     <h3 v-if="row.media.type === 'image'">{{ row.media.file.name }}</h3> |  | ||||||
|                     <h3 v-if="row.media.type === 'link'">{{ row.media.linkUrl }}</h3> |  | ||||||
|                     <h3 v-if="row.media.type === 'video'">{{ row.media.file.name }}</h3> |  | ||||||
|                     <p v-if="row.media.type === 'image'">{{ row.media.file.fileSizeStr }}</p> |  | ||||||
|                     <p v-if="row.media.type === 'link'">{{ row.media.title }}</p> |  | ||||||
|                     <p v-if="row.media.type === 'video'">{{ row.media.file.fileSizeStr }}</p> |  | ||||||
|                   </div> |  | ||||||
|                 </div> |  | ||||||
|               </div> |  | ||||||
|             </el-popover> |  | ||||||
|           </template> |  | ||||||
|         </el-table-column> |  | ||||||
|         <el-table-column slot="options" width="120px" fixed="right" label="操作" align="center"> |  | ||||||
|           <template slot-scope="{ row }"> |  | ||||||
|             <div class="table-options"> |  | ||||||
|               <!-- <el-button type="text" disabled @click="toAdd(row.id)" title="编辑">编辑</el-button> --> |  | ||||||
|               <el-button type="text" @click="remove(row.id)" title="删除">删除</el-button> |  | ||||||
|             </div> |  | ||||||
|           </template> |  | ||||||
|         </el-table-column> |  | ||||||
|       </ai-table> |  | ||||||
|     </template> |  | ||||||
|   </ai-list> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   export default { |  | ||||||
|     name: 'List', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data () { |  | ||||||
|       return { |  | ||||||
|         search: { |  | ||||||
|           current: 1, |  | ||||||
|           size: 10, |  | ||||||
|           content: '' |  | ||||||
|         }, |  | ||||||
|         currIndex: 0, |  | ||||||
|         total: 10, |  | ||||||
|         colConfigs: [ |  | ||||||
|           { prop: 'type',  label: '类型', align: 'left', width: '160', |  | ||||||
|             render: (h, params) => { |  | ||||||
|               let str = '' |  | ||||||
|  |  | ||||||
|               if (params.row.content) { |  | ||||||
|                 str = '文字' |  | ||||||
|               } |  | ||||||
|  |  | ||||||
|               if (params.row.media && params.row.media.type === 'link') { |  | ||||||
|                 str += this.dict.getLabel('wxMsgType', params.row.media.type) ? (params.row.content ? '+' : '') + this.dict.getLabel('wxMsgType', params.row.media.type) : '' |  | ||||||
|               } |  | ||||||
|  |  | ||||||
|               if (params.row.media && params.row.media.file) { |  | ||||||
|                 str += this.dict.getLabel('wxMsgType', params.row.media.type) ? (params.row.content ? '+' : '') + this.dict.getLabel('wxMsgType', params.row.media.type) : '' |  | ||||||
|               } |  | ||||||
|  |  | ||||||
|               return h('span', { |  | ||||||
|                 style: { |  | ||||||
|                 } |  | ||||||
|               }, str) |  | ||||||
|             } |  | ||||||
|           }, |  | ||||||
|           { slot: 'type' }, |  | ||||||
|           { prop: 'users', label: '使用成员', align: 'left', format: v => v.join(';') }, |  | ||||||
|           { prop: 'createUser', label: '创建人' }, |  | ||||||
|           { prop: 'createTime', label: '编辑时间' }, |  | ||||||
|           { slot: 'options', label: '操作' } |  | ||||||
|         ], |  | ||||||
|         tableData: [] |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     mounted () { |  | ||||||
|       this.dict.load(['wxMsgType']).then(() => { |  | ||||||
|         this.getList() |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       getList() { |  | ||||||
|         this.instance.post(`/app/wxcp/wxwelcomeword/list`, null, { |  | ||||||
|           params: { |  | ||||||
|             ...this.search |  | ||||||
|           } |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.tableData = res.data.records.map(item => { |  | ||||||
|               let count = 0 |  | ||||||
|  |  | ||||||
|               if (item.content) { |  | ||||||
|                 count = count + 1 |  | ||||||
|               } |  | ||||||
|  |  | ||||||
|               if (item.media && item.media.type !== 'text') { |  | ||||||
|                 count = count + 1 |  | ||||||
|               } |  | ||||||
|  |  | ||||||
|               item.count = count |  | ||||||
|               return item |  | ||||||
|             }) |  | ||||||
|             this.total = res.data.total |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       remove (id) { |  | ||||||
|         this.$confirm('确定删除该数据?').then(() => { |  | ||||||
|           this.instance.post(`/app/wxcp/wxwelcomeword/delete?id=${id}`).then(res => { |  | ||||||
|             if (res.code == 0) { |  | ||||||
|               this.$message.success('删除成功!') |  | ||||||
|               this.getList() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       toAdd (id) { |  | ||||||
|         this.$emit('change', { |  | ||||||
|           type: 'Add', |  | ||||||
|           params: { |  | ||||||
|             id |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
|   .message { |  | ||||||
|     .count { |  | ||||||
|       cursor: pointer; |  | ||||||
|       color: #2266FF; |  | ||||||
|       font-size: 14px; |  | ||||||
|  |  | ||||||
|       &:hover { |  | ||||||
|         opacity: 0.6; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .message-info { |  | ||||||
|     padding: 8px; |  | ||||||
|     min-height: 116px; |  | ||||||
|  |  | ||||||
|     h2 { |  | ||||||
|       color: #222222; |  | ||||||
|       font-weight: 500; |  | ||||||
|       font-size: 14px; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .message-info__wrapper { |  | ||||||
|       display: flex; |  | ||||||
|       align-items: center; |  | ||||||
|       width: 368px; |  | ||||||
|       height: 60px; |  | ||||||
|       padding: 10px; |  | ||||||
|       background: #FFFFFF; |  | ||||||
|       border-radius: 2px; |  | ||||||
|       border: 1px solid #D0D4DC; |  | ||||||
|  |  | ||||||
|       .message-info__wrapper--right { |  | ||||||
|         flex: 1; |  | ||||||
|         overflow: hidden; |  | ||||||
|         text-overflow:ellipsis; |  | ||||||
|         white-space: nowrap; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       h3 { |  | ||||||
|         width: 100%; |  | ||||||
|         color: #222222; |  | ||||||
|         font-size: 14px; |  | ||||||
|         overflow: hidden; |  | ||||||
|         text-overflow:ellipsis; |  | ||||||
|         white-space: nowrap; |  | ||||||
|         font-weight: normal; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       img, video { |  | ||||||
|         width: 40px; |  | ||||||
|         height: 40px; |  | ||||||
|         margin-right: 10px; |  | ||||||
|         object-fit: cover; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       p { |  | ||||||
|         margin-top: 6px; |  | ||||||
|         font-size: 14px; |  | ||||||
|         color: #888888; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </style> |  | ||||||
| @@ -1,47 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <div class="doc-circulation ailist-wrapper"> |  | ||||||
|     <keep-alive :include="['List']"> |  | ||||||
|       <component ref="component" :is="component" :instance="instance" :dict="dict"></component> |  | ||||||
|     </keep-alive> |  | ||||||
|   </div> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   import List from './components/List' |  | ||||||
|  |  | ||||||
|   export default { |  | ||||||
|     name: 'AppMaterialLibrary', |  | ||||||
|     label: '素材库', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data () { |  | ||||||
|       return { |  | ||||||
|         component: 'List', |  | ||||||
|         params: {}, |  | ||||||
|         include: [] |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     components: { |  | ||||||
|       List |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     mounted () { |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss"> |  | ||||||
|   .doc-circulation { |  | ||||||
|     height: 100%; |  | ||||||
|     background: #F3F6F9; |  | ||||||
|     overflow: auto; |  | ||||||
|   } |  | ||||||
| </style> |  | ||||||
| @@ -1,212 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <div id="ChooseMaterial"> |  | ||||||
|     <ai-dialog |  | ||||||
|       :visible.sync="isShow" |  | ||||||
|       width="890px" |  | ||||||
|       @onConfirm="onConfirm" |  | ||||||
|       title="选择素材"> |  | ||||||
|       <div class="AppMaterialLibrary-title"> |  | ||||||
|         <span |  | ||||||
|           v-for="(item, index) in typeList" |  | ||||||
|           :key="index" |  | ||||||
|           :class="[currIndex === index ? 'active' : '']" @click="currIndex = index, search.current = 1, getList()"> |  | ||||||
|           {{ item }} |  | ||||||
|         </span> |  | ||||||
|       </div> |  | ||||||
|       <ai-search-bar class="search-bar"> |  | ||||||
|         <template #left> |  | ||||||
|         </template> |  | ||||||
|         <template slot="right"> |  | ||||||
|           <el-input |  | ||||||
|             v-model="search.title" |  | ||||||
|             size="small" |  | ||||||
|             v-throttle="() => { search.current = 1, getList() }" |  | ||||||
|             placeholder="请输入标题、话术内容、添加人" |  | ||||||
|             clearable |  | ||||||
|             @clear="search.current = 1, search.title = '', getList()" |  | ||||||
|             suffix-icon="iconfont iconSearch"> |  | ||||||
|           </el-input> |  | ||||||
|         </template> |  | ||||||
|       </ai-search-bar> |  | ||||||
|       <ai-table |  | ||||||
|         :tableData="tableData" |  | ||||||
|         :col-configs="colConfigs" |  | ||||||
|         :total="total" |  | ||||||
|         style="margin-top: 6px; width: 100%;" |  | ||||||
|         :current.sync="search.current" |  | ||||||
|         :size.sync="search.size" |  | ||||||
|         @selection-change="v=> ids = v.map((e) => e.id)" |  | ||||||
|         @getList="getList"> |  | ||||||
|       </ai-table> |  | ||||||
|     </ai-dialog> |  | ||||||
|   </div> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   export default { |  | ||||||
|     name: 'ChooseMaterial', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data() { |  | ||||||
|       return { |  | ||||||
|         search: { |  | ||||||
|           current: 1, |  | ||||||
|           size: 10, |  | ||||||
|           title: '', |  | ||||||
|         }, |  | ||||||
|         ids: [], |  | ||||||
|         isShow: false, |  | ||||||
|         id: '', |  | ||||||
|         typeList: ['话术', '图片', '小程序', '文件', '视频', '网页'], |  | ||||||
|         currIndex: 0, |  | ||||||
|         tableData: [], |  | ||||||
|         total: 0 |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     computed: { |  | ||||||
|       mpTitle () { |  | ||||||
|         return { |  | ||||||
|           '0': '话术标题', |  | ||||||
|           '1': '图片名称', |  | ||||||
|           '2': '小程序标题', |  | ||||||
|           '3': '文件名称', |  | ||||||
|           '4': '视频名称', |  | ||||||
|           '5': '网页名称' |  | ||||||
|         }[this.currIndex] |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       colConfigs () { |  | ||||||
|         if (this.currIndex === 0) { |  | ||||||
|           return [ |  | ||||||
|             { type: 'selection' }, |  | ||||||
|             { prop: 'title', label: this.mpTitle }, |  | ||||||
|             { prop: 'content', label: '话术内容', align: 'center' }, |  | ||||||
|             { prop: 'createUserName', label: '添加人', align: 'center' }, |  | ||||||
|             { prop: 'createTime', label: '添加时间', align: 'center' } |  | ||||||
|           ] |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (this.currIndex === 2) { |  | ||||||
|           return [ |  | ||||||
|             { type: 'selection' }, |  | ||||||
|             { prop: 'title', label: this.mpTitle }, |  | ||||||
|             { prop: 'appId', label: '小程序APPID', align: 'center' }, |  | ||||||
|             { prop: 'createUserName', label: '添加人', align: 'center' }, |  | ||||||
|             { prop: 'createTime', label: '添加时间', align: 'center' } |  | ||||||
|           ] |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (this.currIndex === 5) { |  | ||||||
|           return [ |  | ||||||
|             { type: 'selection' }, |  | ||||||
|             { prop: 'title', label: this.mpTitle }, |  | ||||||
|             { prop: 'pagePath', label: '外链网页', align: 'center' }, |  | ||||||
|             { prop: 'createUserName', label: '添加人', align: 'center' }, |  | ||||||
|             { prop: 'createTime', label: '添加时间', align: 'center' } |  | ||||||
|           ] |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return [ |  | ||||||
|           { type: 'selection' }, |  | ||||||
|           { prop: 'title', label: this.mpTitle }, |  | ||||||
|           { prop: 'fileSizeStr', label: '文件大小', align: 'center' }, |  | ||||||
|           { prop: 'createUserName', label: '添加人', align: 'center' }, |  | ||||||
|           { prop: 'createTime', label: '添加时间', align: 'center' } |  | ||||||
|         ] |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     created () { |  | ||||||
|       this.getList() |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       getList() { |  | ||||||
|         this.instance.post(`/app/appmaterialinfo/list`, null, { |  | ||||||
|           params: { |  | ||||||
|             ...this.search, |  | ||||||
|             type: this.currIndex |  | ||||||
|           } |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.tableData = res.data.records |  | ||||||
|             this.total = res.data.total |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       onConfirm () { |  | ||||||
|         if (!this.ids.length) { |  | ||||||
|           return this.$message.error('请选择素材') |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (this.ids.length > 1) { |  | ||||||
|           return this.$message.error('素材不能多选') |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       open () { |  | ||||||
|         this.isShow = true |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       close () { |  | ||||||
|         this.isShow = false |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
|   #ChooseMaterial { |  | ||||||
|     :deep( .ai-list__content--right-wrapper ) { |  | ||||||
|       padding: 0 20px!important; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     :deep( .el-dialog__header ) { |  | ||||||
|       display: none; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     :deep( .el-dialog__body ) { |  | ||||||
|       padding-top: 0!important; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .AppMaterialLibrary-title { |  | ||||||
|       display: flex; |  | ||||||
|       align-items: center; |  | ||||||
|       margin-bottom: 20px; |  | ||||||
|       border-bottom: 1px solid #eee; |  | ||||||
|  |  | ||||||
|       span { |  | ||||||
|         height: 100%; |  | ||||||
|         line-height: 56px; |  | ||||||
|         margin-right: 32px; |  | ||||||
|         color: #888888; |  | ||||||
|         font-size: 16px; |  | ||||||
|         font-weight: 600; |  | ||||||
|         transition: all ease 0.3s; |  | ||||||
|         border-bottom: 3px solid transparent; |  | ||||||
|         cursor: pointer; |  | ||||||
|         user-select: none; |  | ||||||
|  |  | ||||||
|         &:hover { |  | ||||||
|           color: #222; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         &:last-child { |  | ||||||
|           margin-right: 0; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         &.active { |  | ||||||
|           color: #222222; |  | ||||||
|           border-bottom: 3px solid #2266FF; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </style> |  | ||||||
| @@ -1,394 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <ai-list id="AppMaterialLibrary"> |  | ||||||
|     <template slot="title"> |  | ||||||
|       <ai-title title="素材管理" isShowBottomBorder> |  | ||||||
|         <template #sub> |  | ||||||
|           <span>可在聊天素材、宣发工具中选择素材发送给居民,提升服务效率;其中文件、视频和网页素材支持记录居民查看行为</span> |  | ||||||
|         </template> |  | ||||||
|       </ai-title> |  | ||||||
|     </template> |  | ||||||
|     <template slot="content"> |  | ||||||
|       <div class="AppMaterialLibrary-title"> |  | ||||||
|         <span |  | ||||||
|           v-for="(item, index) in typeList" |  | ||||||
|           :key="index" |  | ||||||
|           :class="[currIndex === index ? 'active' : '']" @click="currIndex = index, search.current = 1, getList()"> |  | ||||||
|           {{ item }} |  | ||||||
|         </span> |  | ||||||
|       </div> |  | ||||||
|       <ai-search-bar class="search-bar"> |  | ||||||
|         <template #left> |  | ||||||
|           <el-button size="small" type="primary" icon="iconfont iconAdd" @click="isShow = true">添加{{ typeList[currIndex] }}</el-button> |  | ||||||
|         </template> |  | ||||||
|         <template slot="right"> |  | ||||||
|           <el-input |  | ||||||
|             v-model="search.title" |  | ||||||
|             size="small" |  | ||||||
|             v-throttle="() => { search.current = 1, getList() }" |  | ||||||
|             placeholder="请输入标题、话术内容、添加人" |  | ||||||
|             clearable |  | ||||||
|             @clear="search.current = 1, search.title = '', getList()" |  | ||||||
|             suffix-icon="iconfont iconSearch"> |  | ||||||
|           </el-input> |  | ||||||
|         </template> |  | ||||||
|       </ai-search-bar> |  | ||||||
|       <ai-table |  | ||||||
|         :tableData="tableData" |  | ||||||
|         :col-configs="colConfigs" |  | ||||||
|         :total="total" |  | ||||||
|         style="margin-top: 6px; width: 100%;" |  | ||||||
|         :current.sync="search.current" |  | ||||||
|         :size.sync="search.size" |  | ||||||
|         @getList="getList"> |  | ||||||
|         <el-table-column slot="options" width="120px" fixed="right" label="操作" align="center"> |  | ||||||
|           <template slot-scope="{ row }"> |  | ||||||
|             <div class="table-options"> |  | ||||||
|               <el-button type="text" @click="id = row.id, toAdd(row)">编辑</el-button> |  | ||||||
|               <el-button type="text" @click="remove(row.id)">删除</el-button> |  | ||||||
|             </div> |  | ||||||
|           </template> |  | ||||||
|         </el-table-column> |  | ||||||
|       </ai-table> |  | ||||||
|       <ai-dialog |  | ||||||
|         :visible.sync="isShow" |  | ||||||
|         width="920px" |  | ||||||
|         :title="(id ? '编辑' : '添加') + typeList[currIndex]" |  | ||||||
|         @close="onClose" |  | ||||||
|         :close-on-click-modal="false" |  | ||||||
|         destroy-on-close |  | ||||||
|         @onConfirm="confirm"> |  | ||||||
|         <el-form ref="form" v-if="isShow" :model="form" label-width="130px" label-position="right"> |  | ||||||
|           <div class="ai-form"> |  | ||||||
|             <el-form-item v-if="currIndex === 0" label="话术标题" style="width: 100%;" prop="title" :rules="[{ required: true, message: '请输入话术标题', trigger: 'blur' }]"> |  | ||||||
|               <el-input |  | ||||||
|                 size="small" |  | ||||||
|                 placeholder="请输入话术标题" |  | ||||||
|                 maxlength="42" |  | ||||||
|                 show-word-limit |  | ||||||
|                 v-model="form.title"> |  | ||||||
|               </el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item v-if="currIndex === 0" label="话术内容" style="width: 100%;" prop="content" :rules="[{ required: true, message: '请输入话术内容', trigger: 'blur' }]"> |  | ||||||
|               <el-input |  | ||||||
|                 size="small" |  | ||||||
|                 placeholder="请输入话术内容" |  | ||||||
|                 maxlength="682" |  | ||||||
|                 show-word-limit |  | ||||||
|                 v-model="form.content"> |  | ||||||
|               </el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item v-if="currIndex === 1" label="图片名称" style="width: 100%;" prop="title" :rules="[{ required: true, message: '请输入图片名称', trigger: 'blur' }]"> |  | ||||||
|               <el-input |  | ||||||
|                 size="small" |  | ||||||
|                 placeholder="请输入图片名称" |  | ||||||
|                 maxlength="42" |  | ||||||
|                 show-word-limit |  | ||||||
|                 v-model="form.title"> |  | ||||||
|               </el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item v-if="currIndex === 1" label="上传图片" style="width: 100%;" prop="fileUrl" :rules="[{ required: true, message: '请上传', trigger: 'change' }]"> |  | ||||||
|               <ai-uploader :instance="instance" url="/admin/file/add3?type=image" v-model="form.fileUrl" :limit="1"></ai-uploader> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item v-if="currIndex === 3" label="文件名称" style="width: 100%;" prop="title" :rules="[{ required: true, message: '请输入文件名称', trigger: 'blur' }]"> |  | ||||||
|               <el-input |  | ||||||
|                 size="small" |  | ||||||
|                 placeholder="请输入图片名称" |  | ||||||
|                 maxlength="42" |  | ||||||
|                 show-word-limit |  | ||||||
|                 v-model="form.title"> |  | ||||||
|               </el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item v-if="currIndex === 3" label="上传文件" style="width: 100%;" prop="fileUrl" :rules="[{ required: true, message: '请上传', trigger: 'change' }]"> |  | ||||||
|               <ai-uploader fileType="file" url="/admin/file/add3?type=file" :instance="instance" v-model="form.fileUrl" :limit="1"></ai-uploader> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item v-if="currIndex === 4" label="视频标题" style="width: 100%;" prop="title" :rules="[{ required: true, message: '请输入视频标题', trigger: 'blur' }]"> |  | ||||||
|               <el-input |  | ||||||
|                 size="small" |  | ||||||
|                 placeholder="请输入视频标题" |  | ||||||
|                 maxlength="42" |  | ||||||
|                 show-word-limit |  | ||||||
|                 v-model="form.title"> |  | ||||||
|               </el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item v-if="currIndex === 4" label="上传视频" style="width: 100%;" prop="fileUrl" :rules="[{ required: true, message: '请上传', trigger: 'change' }]"> |  | ||||||
|               <ai-uploader :instance="instance" url="/admin/file/add3?type=video" fileType="file" v-model="form.fileUrl" :limit="1"></ai-uploader> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item v-if="currIndex === 4" label="视频封面图" prop="pictureUrl" style="width: 100%;" :rules="[{ required: true, message: '请上传视频封面图', trigger: 'change' }]"> |  | ||||||
|               <ai-uploader :instance="instance" url="/admin/file/add3?type=image" v-model="form.pictureUrl" :limit="1"></ai-uploader> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item v-if="currIndex === 4" label="视频描述" style="width: 100%;" prop="content" :rules="[{ required: true, message: '请输入视频描述', trigger: 'blur' }]"> |  | ||||||
|               <el-input |  | ||||||
|                 size="small" |  | ||||||
|                 placeholder="请输入视频描述" |  | ||||||
|                 maxlength="682" |  | ||||||
|                 show-word-limit |  | ||||||
|                 v-model="form.content"> |  | ||||||
|               </el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item v-if="currIndex === 5" label="网页标题" style="width: 100%;" prop="title" :rules="[{ required: true, message: '请输入网页标题', trigger: 'blur' }]"> |  | ||||||
|               <el-input |  | ||||||
|                 size="small" |  | ||||||
|                 placeholder="请输入网页标题" |  | ||||||
|                 maxlength="42" |  | ||||||
|                 show-word-limit |  | ||||||
|                 v-model="form.title"> |  | ||||||
|               </el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item v-if="currIndex === 5" label="网页链接" style="width: 100%;" prop="pagePath" :rules="[{ required: true, message: '请输入网页链接链接', trigger: 'blur' }]"> |  | ||||||
|               <el-input |  | ||||||
|                 size="small" |  | ||||||
|                 placeholder="请输入网页链接链接" |  | ||||||
|                 maxlength="682" |  | ||||||
|                 show-word-limit |  | ||||||
|                 v-model="form.pagePath"> |  | ||||||
|               </el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item v-if="form.currIndex === 5" label="网页描述" style="width: 100%;" prop="content"> |  | ||||||
|               <el-input |  | ||||||
|                 size="small" |  | ||||||
|                 placeholder="请输入网页描述" |  | ||||||
|                 maxlength="170" |  | ||||||
|                 show-word-limit |  | ||||||
|                 v-model="form.content"> |  | ||||||
|               </el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item v-if="currIndex === 5" label="网页封面图" prop="pictureUrl" style="width: 100%;" :rules="[{ required: true, message: '请上传封面图', trigger: 'change' }]"> |  | ||||||
|               <ai-uploader :instance="instance" url="/admin/file/add3?type=image" v-model="form.pictureUrl" :limit="1"></ai-uploader> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item v-if="currIndex === 2" label="小程序标题" style="width: 100%;" prop="title" :rules="[{ required: true, message: '请输入小程序标题', trigger: 'blur' }]"> |  | ||||||
|               <el-input |  | ||||||
|                 size="small" |  | ||||||
|                 placeholder="请输入小程序标题" |  | ||||||
|                 maxlength="20" |  | ||||||
|                 show-word-limit |  | ||||||
|                 v-model="form.title"> |  | ||||||
|               </el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item v-if="currIndex === 2" label="小程序appid" style="width: 100%;" prop="appId" :rules="[{ required: true, message: '小程序appid', trigger: 'blur' }]"> |  | ||||||
|               <el-input |  | ||||||
|                 size="small" |  | ||||||
|                 placeholder="小程序appid" |  | ||||||
|                 v-model="form.appId"> |  | ||||||
|               </el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item v-if="currIndex === 2" label="小程序路径" style="width: 100%;" prop="pagePath" :rules="[{ required: true, message: '请输入小程序路径', trigger: 'blur' }]"> |  | ||||||
|               <el-input |  | ||||||
|                 size="small" |  | ||||||
|                 placeholder="请输入小程序page路径" |  | ||||||
|                 v-model="form.pagePath"> |  | ||||||
|               </el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item v-if="currIndex === 2" label="小程序封面图" prop="pictureUrl" style="width: 100%;" :rules="[{ required: true, message: '请上传封面图', trigger: 'change' }]"> |  | ||||||
|               <ai-uploader :instance="instance" url="/admin/file/add3?type=image" v-model="form.pictureUrl" :limit="1"></ai-uploader> |  | ||||||
|             </el-form-item> |  | ||||||
|           </div> |  | ||||||
|         </el-form> |  | ||||||
|       </ai-dialog> |  | ||||||
|     </template> |  | ||||||
|   </ai-list> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   export default { |  | ||||||
|     name: 'List', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data() { |  | ||||||
|       return { |  | ||||||
|         search: { |  | ||||||
|           current: 1, |  | ||||||
|           size: 10, |  | ||||||
|           title: '', |  | ||||||
|         }, |  | ||||||
|         isShow: false, |  | ||||||
|         form: { |  | ||||||
|           appId: '', |  | ||||||
|           content: '', |  | ||||||
|           fileUrl: [], |  | ||||||
|           pagePath: '', |  | ||||||
|           pictureUrl: [], |  | ||||||
|           title: '' |  | ||||||
|         }, |  | ||||||
|         id: '', |  | ||||||
|         typeList: ['话术', '图片', '小程序', '文件', '视频', '网页'], |  | ||||||
|         currIndex: 0, |  | ||||||
|         tableData: [], |  | ||||||
|         total: 0 |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     computed: { |  | ||||||
|       mpTitle () { |  | ||||||
|         return { |  | ||||||
|           '0': '话术标题', |  | ||||||
|           '1': '图片名称', |  | ||||||
|           '2': '小程序标题', |  | ||||||
|           '3': '文件名称', |  | ||||||
|           '4': '视频名称', |  | ||||||
|           '5': '网页名称' |  | ||||||
|         }[this.currIndex] |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       colConfigs () { |  | ||||||
|         if (this.currIndex === 0) { |  | ||||||
|           return [ |  | ||||||
|             { prop: 'title', label: this.mpTitle }, |  | ||||||
|             { prop: 'content', label: '话术内容', align: 'center' }, |  | ||||||
|             { prop: 'createUserName', label: '添加人', align: 'center' }, |  | ||||||
|             { prop: 'createTime', label: '添加时间', align: 'center' } |  | ||||||
|           ] |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (this.currIndex === 2) { |  | ||||||
|           return [ |  | ||||||
|             { prop: 'title', label: this.mpTitle }, |  | ||||||
|             { prop: 'appId', label: '小程序APPID', align: 'center' }, |  | ||||||
|             { prop: 'createUserName', label: '添加人', align: 'center' }, |  | ||||||
|             { prop: 'createTime', label: '添加时间', align: 'center' } |  | ||||||
|           ] |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (this.currIndex === 5) { |  | ||||||
|           return [ |  | ||||||
|             { prop: 'title', label: this.mpTitle }, |  | ||||||
|             { prop: 'pagePath', label: '外链网页', align: 'center' }, |  | ||||||
|             { prop: 'createUserName', label: '添加人', align: 'center' }, |  | ||||||
|             { prop: 'createTime', label: '添加时间', align: 'center' } |  | ||||||
|           ] |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return [ |  | ||||||
|           { prop: 'title', label: this.mpTitle }, |  | ||||||
|           { prop: 'fileSizeStr', label: '文件大小', align: 'center' }, |  | ||||||
|           { prop: 'createUserName', label: '添加人', align: 'center' }, |  | ||||||
|           { prop: 'createTime', label: '添加时间', align: 'center' } |  | ||||||
|         ] |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     created () { |  | ||||||
|       this.getList() |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       getList() { |  | ||||||
|         this.instance.post(`/app/appmaterialinfo/list`, null, { |  | ||||||
|           params: { |  | ||||||
|             ...this.search, |  | ||||||
|             type: this.currIndex |  | ||||||
|           } |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.tableData = res.data.records |  | ||||||
|             this.total = res.data.total |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       toAdd (e) { |  | ||||||
|         this.form = { |  | ||||||
|           ...this.form, |  | ||||||
|           ...e, |  | ||||||
|           fileUrl: e.fileUrl ? [{ |  | ||||||
|             url: e.fileUrl |  | ||||||
|           }] : '', |  | ||||||
|           pictureUrl: e.pictureUrl ? [{ |  | ||||||
|             url: e.pictureUrl |  | ||||||
|           }] : '' |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this.isShow = true |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       onClose () { |  | ||||||
|         this.form.content = '' |  | ||||||
|         this.form.appId = '' |  | ||||||
|         this.form.fileUrl = [] |  | ||||||
|         this.form.pagePath = '' |  | ||||||
|         this.form.pictureUrl = [] |  | ||||||
|         this.form.title = '' |  | ||||||
|  |  | ||||||
|         this.id = '' |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       confirm () { |  | ||||||
|         this.$refs.form.validate((valid) => { |  | ||||||
|           if (valid) { |  | ||||||
|             this.instance.post(`/app/appmaterialinfo/addOrUpdate`, { |  | ||||||
|               ...this.form, |  | ||||||
|               type: this.currIndex, |  | ||||||
|               fileUrl: this.form.fileUrl.length ? this.form.fileUrl[0].url : '', |  | ||||||
|               fileId: this.form.fileUrl.length ? this.form.fileUrl[0].id : '', |  | ||||||
|               pictureId: this.form.pictureUrl.length ? this.form.pictureUrl[0].id : '', |  | ||||||
|               pictureUrl: this.form.pictureUrl.length ? this.form.pictureUrl[0].url : '', |  | ||||||
|               fileSize: this.form.fileUrl.length ? this.form.fileUrl[0].fileSize : '', |  | ||||||
|             }).then(res => { |  | ||||||
|               if (res.code == 0) { |  | ||||||
|                 this.$message.success('提交成功') |  | ||||||
|                 this.isShow = false |  | ||||||
|  |  | ||||||
|                 this.getList() |  | ||||||
|               } |  | ||||||
|             }) |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       remove (id) { |  | ||||||
|         this.$confirm('确定删除该数据?').then(() => { |  | ||||||
|           this.instance.post(`/app/appmaterialinfo/delete?ids=${id}`).then(res => { |  | ||||||
|             if (res.code == 0) { |  | ||||||
|               this.$message.success('删除成功!') |  | ||||||
|               this.getList() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         }) |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
|   #AppMaterialLibrary { |  | ||||||
|     :deep( .ai-list__content--right-wrapper ) { |  | ||||||
|       padding: 0 20px!important; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .AppMaterialLibrary-title { |  | ||||||
|       display: flex; |  | ||||||
|       align-items: center; |  | ||||||
|       margin-bottom: 20px; |  | ||||||
|       border-bottom: 1px solid #eee; |  | ||||||
|  |  | ||||||
|       span { |  | ||||||
|         height: 100%; |  | ||||||
|         line-height: 56px; |  | ||||||
|         margin-right: 32px; |  | ||||||
|         color: #888888; |  | ||||||
|         font-size: 16px; |  | ||||||
|         font-weight: 600; |  | ||||||
|         transition: all ease 0.3s; |  | ||||||
|         border-bottom: 3px solid transparent; |  | ||||||
|         cursor: pointer; |  | ||||||
|         user-select: none; |  | ||||||
|  |  | ||||||
|         &:hover { |  | ||||||
|           color: #222; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         &:last-child { |  | ||||||
|           margin-right: 0; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         &.active { |  | ||||||
|           color: #222222; |  | ||||||
|           border-bottom: 3px solid #2266FF; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </style> |  | ||||||
| @@ -1,617 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <section style="height: 100%;"> |  | ||||||
|     <ai-list> |  | ||||||
|       <template slot="title"> |  | ||||||
|         <ai-title title="话术库" :isShowBottomBorder="true"></ai-title> |  | ||||||
|       </template> |  | ||||||
|       <template #left> |  | ||||||
|         <div class="left-tree"> |  | ||||||
|           <div class="tree-title"> |  | ||||||
|             <label>分组</label> |  | ||||||
|             <el-button icon="iconfont iconAdd" style="height: 28px;line-height: 0;" @click="groupDialog = true">添加分组 |  | ||||||
|             </el-button> |  | ||||||
|           </div> |  | ||||||
|           <el-scrollbar style="height: calc(100% - 40px)"> |  | ||||||
|             <el-menu style="height: 100%;" default-active="0" active-text-color="#26f" text-color="#222" |  | ||||||
|                      mode="vertical"> |  | ||||||
|               <el-menu-item v-for="(item, index) in sortList" :key="index" class="menu-item" @click="currentMenu(item)" |  | ||||||
|                             :index="index.toString()"> |  | ||||||
|                 <label class="item-title">{{ item.name }}</label> |  | ||||||
|                 <el-popover style="width: 30px" placement="left" trigger="click"> |  | ||||||
|                   <div style="display: flex;flex-direction: column;align-items: center;"> |  | ||||||
|                     <div style="cursor: pointer;" @click="editGroup(item, index)">编辑</div> |  | ||||||
|                     <div style="cursor: pointer;" @click="delteGroup(item, index)">删除</div> |  | ||||||
|                   </div> |  | ||||||
|                   <span class="iconfont iconMore" slot="reference"></span> |  | ||||||
|                 </el-popover> |  | ||||||
|               </el-menu-item> |  | ||||||
|             </el-menu> |  | ||||||
|           </el-scrollbar> |  | ||||||
|         </div> |  | ||||||
|       </template> |  | ||||||
|       <template slot="content"> |  | ||||||
|         <ai-search-bar> |  | ||||||
|           <template slot="left"> |  | ||||||
|             <el-select v-model="search.contentType" placeholder="类型" size="small" clearable @change="getList()"> |  | ||||||
|               <el-option v-for="(item, index) in types" :key="index" :label="item.name" :value="item.value"></el-option> |  | ||||||
|             </el-select> |  | ||||||
|           </template> |  | ||||||
|           <template slot="right"> |  | ||||||
|             <el-input v-model="search.title" class="search-input" size="small" |  | ||||||
|                       @keyup.enter.native=";(search.current = 1), getList()" placeholder="请输入标题或话术内容或创建人" clearable |  | ||||||
|                       @clear=";(search.current = 1), (search.title = ''), getList()" suffix-icon="iconfont iconSearch"/> |  | ||||||
|           </template> |  | ||||||
|         </ai-search-bar> |  | ||||||
|         <ai-search-bar> |  | ||||||
|           <template slot="left"> |  | ||||||
|             <el-button icon="iconfont iconAdd" type="primary" @click="add">添加话术</el-button> |  | ||||||
|           </template> |  | ||||||
|         </ai-search-bar> |  | ||||||
|         <ai-table :tableData="tableData" :col-configs="colConfigs" :stripe="true" :total="total" ref="aitableex" |  | ||||||
|                   style="margin-top: 8px;" :current.sync="search.current" :size.sync="search.size" @getList="getList">\ |  | ||||||
|  |  | ||||||
|           <el-table-column slot="content" label="话术内容" align="left" width="280"> |  | ||||||
|             <template slot-scope="{ row }"> |  | ||||||
|               <div class="table-left__wrapper"> |  | ||||||
|                 <video :src="row.file && row.file.url" v-if="row.file && row.contentType == 'video'" |  | ||||||
|                        class="media"></video> |  | ||||||
|                 <img :src="row.file && row.file.url" v-if="row.file && row.contentType == 'image'" class="media"/> |  | ||||||
|                 <audio :src="row.file && row.file.url" v-if="row.file && row.contentType == 'voice'" |  | ||||||
|                        class="media"></audio> |  | ||||||
|                 <div class="table-left__wrapper--right"> |  | ||||||
|                   <el-tooltip class="item" effect="dark" :content="row.content" placement="top"> |  | ||||||
|                     <div class="table-left__wrapper--text" v-if="row.contentType == 'text'">{{ row.content }}</div> |  | ||||||
|                   </el-tooltip> |  | ||||||
|                   <div class="ellipsis" v-if="row.contentType !== 'text' && row.file && row.file.name">{{ row.file.name }}</div> |  | ||||||
|                   <div v-if="row.contentType !== 'text' && row.file && row.file.size">{{ row.file.size | size }}KB</div> |  | ||||||
|                 </div> |  | ||||||
|               </div> |  | ||||||
|             </template> |  | ||||||
|           </el-table-column> |  | ||||||
|  |  | ||||||
|  |  | ||||||
|           <el-table-column slot="options" label="操作" width="160px" align="center" fixed="right"> |  | ||||||
|             <template slot-scope="{ row }"> |  | ||||||
|               <span class="table-btn" title="编辑" @click="editTrick(row)">编辑</span> |  | ||||||
|               <span class="table-btn" title="删除" @click="deleteTrick(row)">删除</span> |  | ||||||
|             </template> |  | ||||||
|           </el-table-column> |  | ||||||
|         </ai-table> |  | ||||||
|       </template> |  | ||||||
|     </ai-list> |  | ||||||
|     <ai-dialog :visible.sync="groupDialog" @closed="sortForm = {},sortForm.type=1" width="800px" title="添加分组" |  | ||||||
|                @onConfirm="onConfirm"> |  | ||||||
|       <el-form size="small" label-width="100px" ref="groupForm" :model="sortForm" :rules="sortRules"> |  | ||||||
|         <el-form-item label="分组名称" prop="name"> |  | ||||||
|           <el-input clearable v-model.trim="sortForm.name" placeholder="请输入..." :maxlength="10" show-word-limit/> |  | ||||||
|         </el-form-item> |  | ||||||
|         <!--        <el-form-item label="可见范围" prop="type">--> |  | ||||||
|         <!--          <el-radio-group v-model="sortForm.type">--> |  | ||||||
|         <!--            <el-radio label="0">个人话术</el-radio>--> |  | ||||||
|         <!--            <el-radio label="1">公共话术</el-radio>--> |  | ||||||
|         <!--          </el-radio-group>--> |  | ||||||
|         <!--        </el-form-item>--> |  | ||||||
|         <!--        <el-form-item label="可用部门" prop="documentName">--> |  | ||||||
|         <!--          <el-row type="flex">--> |  | ||||||
|         <!--            <div class="input"></div>--> |  | ||||||
|         <!--            <ai-person-select :instance="instance" url="/app/appvillagecadres/list" :isMultiple="true"--> |  | ||||||
|         <!--                              btnText="选择" dialogTitle="选择">--> |  | ||||||
|         <!--              <template name="option" v-slot:option="{ item }">--> |  | ||||||
|         <!--                <span class="iconfont iconProlife">{{ item.name }}</span>--> |  | ||||||
|         <!--                <ai-id mode="show" :show-eyes="false" :value="item.idNumber"/>--> |  | ||||||
|         <!--              </template>--> |  | ||||||
|         <!--            </ai-person-select>--> |  | ||||||
|         <!--          </el-row>--> |  | ||||||
|         <!--        </el-form-item>--> |  | ||||||
|       </el-form> |  | ||||||
|     </ai-dialog> |  | ||||||
|  |  | ||||||
|     <ai-dialog :visible.sync="trickDialog" @close="onClose" @onConfirm="trickConfirm" width="800px" title="添加话术"> |  | ||||||
|       <el-form size="small" label-width="100px" ref="trickFom" :model="trickForm" :rules="trickRules"> |  | ||||||
|         <!--        <el-form-item label="分组" prop="handleResult">--> |  | ||||||
|         <!--          <ai-select--> |  | ||||||
|         <!--            v-model="search.type"--> |  | ||||||
|         <!--            @change="search.current = 1, getList()"--> |  | ||||||
|         <!--            placeholder="类型"--> |  | ||||||
|         <!--            :selectList="sortList"--> |  | ||||||
|         <!--          ></ai-select>--> |  | ||||||
|         <!--        </el-form-item>--> |  | ||||||
|         <el-form-item label="标题" prop="title"> |  | ||||||
|           <el-input clearable placeholder="请输入..." v-model="trickForm.title" show-word-limit :maxlength="20"/> |  | ||||||
|         </el-form-item> |  | ||||||
|         <el-form-item label="话术类型" prop="contentType"> |  | ||||||
|           <el-radio-group v-model="trickForm.contentType" @change="onChange"> |  | ||||||
|             <el-radio :label="item.value" v-for="(item, index) in types" :key="index">{{ item.name }}</el-radio> |  | ||||||
|           </el-radio-group> |  | ||||||
|         </el-form-item> |  | ||||||
|         <el-form-item label="文本内容" class="el-form-item__textarea" prop="content" v-if="trickForm.contentType == 'text'"> |  | ||||||
|           <span @click="insertNickname" class="el-form-item__btn" type="text">[插入用户昵称]</span> |  | ||||||
|           <span @click="insertRemark" class="el-form-item__remark" type="text">[插入备注名]</span> |  | ||||||
|           <el-input type="textarea" v-model="trickForm.content" placeholder="请输入..." :rows="5" show-word-limit |  | ||||||
|                     :maxlength="255"/> |  | ||||||
|         </el-form-item> |  | ||||||
|         <el-form-item :label="compLabel" prop="fileId" v-else> |  | ||||||
|           <ai-uploader :instance="instance" v-model="fileList" :acceptType="acceptType" |  | ||||||
|                        :url="'/app/wxcp/upload/uploadFile?type=' + trickForm.contentType" isWechat :fileType="fileType" |  | ||||||
|                        :limit="1" @change="change"></ai-uploader> |  | ||||||
|         </el-form-item> |  | ||||||
|       </el-form> |  | ||||||
|     </ai-dialog> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| import {mapState} from 'vuex' |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: 'AppVerbalTrick', |  | ||||||
|   label: '话术库', |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function, |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       groupDialog: false, |  | ||||||
|       trickDialog: false, |  | ||||||
|       search: { |  | ||||||
|         current: 1, |  | ||||||
|         size: 10, |  | ||||||
|         contentType: '', |  | ||||||
|       }, |  | ||||||
|       sortForm: { |  | ||||||
|         name: '', |  | ||||||
|         type: '1', |  | ||||||
|       }, |  | ||||||
|       trickForm: { |  | ||||||
|         title: '', |  | ||||||
|         contentType: 'text', |  | ||||||
|         content: '', |  | ||||||
|         fileId: '', |  | ||||||
|         mediaId: '', |  | ||||||
|       }, |  | ||||||
|       row: {}, |  | ||||||
|       current: {}, |  | ||||||
|       sortList: [], |  | ||||||
|       total: 0, |  | ||||||
|       tableData: [], |  | ||||||
|       fileList: [], |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|  |  | ||||||
|   computed: { |  | ||||||
|     ...mapState(['user']), |  | ||||||
|     acceptType() { |  | ||||||
|       return { |  | ||||||
|         "image": ".jpg,.png,.jpeg", |  | ||||||
|         "video": ".mp4" |  | ||||||
|       }[this.trickForm.contentType] |  | ||||||
|     }, |  | ||||||
|     compLabel() { |  | ||||||
|       return this.types.find((e) => e.value == this.trickForm.contentType)?.name |  | ||||||
|     }, |  | ||||||
|     fileType() { |  | ||||||
|       return this.trickForm.contentType == 'image' ? 'img' : 'file' |  | ||||||
|     }, |  | ||||||
|     types() { |  | ||||||
|       return [ |  | ||||||
|         {name: '文本', value: 'text'}, |  | ||||||
|         {name: '图片', value: 'image'}, |  | ||||||
|         {name: '视频', value: 'video'}, |  | ||||||
|         // // {name: "附件", value: "file"}, |  | ||||||
|         // {name: "音频", value: "voice"}, |  | ||||||
|       ] |  | ||||||
|     }, |  | ||||||
|     trickRules() { |  | ||||||
|       return { |  | ||||||
|         title: [{required: true, message: '请输入标题', trigger: 'blur'}], |  | ||||||
|         contentType: [{required: true, message: '请选择话术类型', trigger: 'change'}], |  | ||||||
|         content: [{required: true, validator: (rule, value, callback)=>{ |  | ||||||
|             if(this.trickForm.contentType == 'text' && !value){ |  | ||||||
|               return callback("请输入文本内容") |  | ||||||
|             }else { |  | ||||||
|               callback() |  | ||||||
|             } |  | ||||||
|           }}], |  | ||||||
|         fileId: [{required: true, validator: (rule, value, callback)=>{ |  | ||||||
|             if(this.trickForm.contentType != 'text' && !value){ |  | ||||||
|               return callback("请上传文件") |  | ||||||
|             }else { |  | ||||||
|               callback() |  | ||||||
|             } |  | ||||||
|           }}], |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     // message() { |  | ||||||
|     //   return (() => { |  | ||||||
|     //     if (this.trickForm.contentType == 'text') { |  | ||||||
|     //       return '请输入文本内容' |  | ||||||
|     //     } else if (this.trickForm.contentType == 'image') { |  | ||||||
|     //       return '请上传图片' |  | ||||||
|     //     } else if (this.trickForm.contentType == 'file') { |  | ||||||
|     //       return '请上传文件' |  | ||||||
|     //     } else if (this.trickForm.contentType == 'video') { |  | ||||||
|     //       return '请上传视频' |  | ||||||
|     //     } else if (this.trickForm.contentType == 'voice') { |  | ||||||
|     //       return '请上传音频' |  | ||||||
|     //     } |  | ||||||
|     //   })() |  | ||||||
|     // }, |  | ||||||
|     sortRules() { |  | ||||||
|       return { |  | ||||||
|         name: [{required: true, message: '请输入分组名称', trigger: 'blur'}], |  | ||||||
|         type: [{required: true, message: '请选择可见范围', trigger: 'change'}], |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     colConfigs() { |  | ||||||
|       return [ |  | ||||||
|         {slot: 'type'}, |  | ||||||
|         {slot: 'content'}, |  | ||||||
|         {prop: 'title', label: '标题'}, |  | ||||||
|         { |  | ||||||
|           prop: 'contentType', |  | ||||||
|           label: '类型', |  | ||||||
|           align: 'center', |  | ||||||
|           render: (h, {row}) => { |  | ||||||
|             return h('span', {}, this.types.find((e) => row.contentType == e.value)?.name) |  | ||||||
|           }, |  | ||||||
|         }, |  | ||||||
|         {prop: 'userName', label: '创建人', align: 'center'}, |  | ||||||
|         {prop: 'createTime', label: '创建时间', align: 'center'}, |  | ||||||
|         {slot: 'options', label: '操作', align: 'center'}, |  | ||||||
|       ] |  | ||||||
|     }, |  | ||||||
|   }, |  | ||||||
|  |  | ||||||
|   created() { |  | ||||||
|     this.getSortList() |  | ||||||
|   }, |  | ||||||
|  |  | ||||||
|   filters: { |  | ||||||
|     size(size) { |  | ||||||
|       return (size / 1024).toFixed(1) |  | ||||||
|     }, |  | ||||||
|   }, |  | ||||||
|  |  | ||||||
|   methods: { |  | ||||||
|     insertNickname() { |  | ||||||
|       this.trickForm.content += '[用户昵称]' |  | ||||||
|     }, |  | ||||||
|     insertRemark() { |  | ||||||
|       this.trickForm.content += '[备注名]' |  | ||||||
|     }, |  | ||||||
|     onClose() { |  | ||||||
|       this.trickForm.title = '' |  | ||||||
|       this.trickForm.content = '' |  | ||||||
|       this.trickForm.fileId = '' |  | ||||||
|       this.trickForm.mediaId = '' |  | ||||||
|       this.trickForm.createdAt = '' |  | ||||||
|       this.trickForm.contentType = 'text' |  | ||||||
|       this.fileList = [] |  | ||||||
|     }, |  | ||||||
|     onChange() { |  | ||||||
|       this.trickForm.fileId = '' |  | ||||||
|       this.trickForm.content = '' |  | ||||||
|       this.trickForm.mediaId = '' |  | ||||||
|       this.trickForm.createdAt = '' |  | ||||||
|       this.fileList = [] |  | ||||||
|     }, |  | ||||||
|     add() { |  | ||||||
|       if (this.sortList.length == 0) return this.$message.error('请先添加分组') |  | ||||||
|       this.$nextTick(() => { |  | ||||||
|         this.trickDialog = true |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     change(e) { |  | ||||||
|       if(e.length){ |  | ||||||
|         this.trickForm.fileId = e[0].id |  | ||||||
|         this.trickForm.mediaId = e[0].media.mediaId |  | ||||||
|         this.trickForm.createdAt = e[0].media.createdAt |  | ||||||
|       }else { |  | ||||||
|         this.trickForm.fileId ="" |  | ||||||
|         this.trickForm.mediaId = "" |  | ||||||
|         this.trickForm.createdAt = "" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     editTrick(row) { |  | ||||||
|       this.row = row |  | ||||||
|       this.trickForm = {...row} |  | ||||||
|       row.file && (this.trickForm.fileId = row.file.id) |  | ||||||
|       this.$nextTick(() => { |  | ||||||
|         this.trickDialog = true |  | ||||||
|       }) |  | ||||||
|       this.fileList.push(row.file) |  | ||||||
|     }, |  | ||||||
|     deleteTrick(row) { |  | ||||||
|       this.$confirm('确认要删除吗?').then(() => { |  | ||||||
|         this.instance |  | ||||||
|         .post(`/app/wxcp/wxspeechtechnique/delete`, null, { |  | ||||||
|           params: { |  | ||||||
|             id: row.id, |  | ||||||
|           }, |  | ||||||
|         }) |  | ||||||
|         .then((res) => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.$message.success('删除成功') |  | ||||||
|             this.getList() |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     trickConfirm() { |  | ||||||
|       this.$refs['trickFom'].validate((valid) => { |  | ||||||
|         if (valid) { |  | ||||||
|           this.instance |  | ||||||
|           .post(`/app/wxcp/wxspeechtechnique/addOrUpdate`, { |  | ||||||
|             ...this.trickForm, |  | ||||||
|             category: this.current.id, |  | ||||||
|             userId: this.user.info.id, |  | ||||||
|           }) |  | ||||||
|           .then((res) => { |  | ||||||
|             if (res.code == 0) { |  | ||||||
|               this.trickDialog = false |  | ||||||
|               this.$message.success(this.trickForm.id ? '编辑成功' : '添加成功') |  | ||||||
|               this.getList() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     currentMenu(item) { |  | ||||||
|       this.current = item |  | ||||||
|       this.getList() |  | ||||||
|     }, |  | ||||||
|     delteGroup(item, index) { |  | ||||||
|       this.$confirm('是否要删除?').then(() => { |  | ||||||
|         this.instance |  | ||||||
|         .post(`/app/wxcp/wxspeechtechniquecategory/delete`, null, { |  | ||||||
|           params: { |  | ||||||
|             id: item.id, |  | ||||||
|           }, |  | ||||||
|         }) |  | ||||||
|         .then((res) => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.$message.success('删除成功') |  | ||||||
|             this.getSortList() |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     editGroup(item, index) { |  | ||||||
|       this.sortForm = {...item} |  | ||||||
|       this.groupDialog = true |  | ||||||
|     }, |  | ||||||
|     onConfirm() { |  | ||||||
|       this.$refs['groupForm'].validate((valid) => { |  | ||||||
|         if (valid) { |  | ||||||
|           this.instance |  | ||||||
|           .post(`/app/wxcp/wxspeechtechniquecategory/addOrUpdate`, { |  | ||||||
|             ...this.sortForm, |  | ||||||
|           }) |  | ||||||
|           .then((res) => { |  | ||||||
|             if (res.code == 0) { |  | ||||||
|               this.groupDialog = false |  | ||||||
|               this.$message.success(this.sortForm.id ? '编辑成功' : '添加成功') |  | ||||||
|               this.getSortList() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     getSortList() { |  | ||||||
|       this.instance |  | ||||||
|       .post(`/app/wxcp/wxspeechtechniquecategory/listAll`, null, { |  | ||||||
|         params: { |  | ||||||
|           // type: 1, |  | ||||||
|         }, |  | ||||||
|       }) |  | ||||||
|       .then((res) => { |  | ||||||
|         if (res && res.data.length) { |  | ||||||
|           this.sortList = res.data |  | ||||||
|           this.current = res.data[0] |  | ||||||
|           this.getList() |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     getList(item) { |  | ||||||
|       this.instance |  | ||||||
|       .post(`/app/wxcp/wxspeechtechnique/list`, null, { |  | ||||||
|         params: { |  | ||||||
|           category: this.current.id, |  | ||||||
|           ...this.search, |  | ||||||
|           status: 1, |  | ||||||
|         }, |  | ||||||
|       }) |  | ||||||
|       .then((res) => { |  | ||||||
|         if (res.code == 0) { |  | ||||||
|           this.tableData = res.data.records |  | ||||||
|           this.total = res.data.total |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|   }, |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
| .left-tree { |  | ||||||
|   width: 264px; |  | ||||||
|   background: #fafafb; |  | ||||||
|   box-shadow: -1px 0px 0px 0px #e5e5e5; |  | ||||||
|   border-radius: 2px 0px 0px 2px; |  | ||||||
|  |  | ||||||
|   .tree-title { |  | ||||||
|     height: 40px; |  | ||||||
|     box-sizing: border-box; |  | ||||||
|     padding: 0 8px 0 16px; |  | ||||||
|     background: #eeeff1; |  | ||||||
|     display: flex; |  | ||||||
|     align-items: center; |  | ||||||
|     justify-content: space-between; |  | ||||||
|  |  | ||||||
|     & > label { |  | ||||||
|       font-size: 14px; |  | ||||||
|       font-weight: bold; |  | ||||||
|       color: #222222; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .tree-item { |  | ||||||
|     box-sizing: border-box; |  | ||||||
|     padding: 8px 16px 8px 24px; |  | ||||||
|     height: 40px; |  | ||||||
|     display: flex; |  | ||||||
|     align-items: center; |  | ||||||
|     justify-content: space-between; |  | ||||||
|     border-right: 2px solid transparent; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .menu-item { |  | ||||||
|     height: 40px; |  | ||||||
|     align-items: center; |  | ||||||
|     display: flex; |  | ||||||
|     justify-content: space-between; |  | ||||||
|  |  | ||||||
|     .item-title { |  | ||||||
|       display: inline-block; |  | ||||||
|       width: 160px; |  | ||||||
|       overflow: hidden; |  | ||||||
|       text-overflow: ellipsis; |  | ||||||
|       white-space: nowrap; |  | ||||||
|       font-size: 14px; |  | ||||||
|       color: #222222; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .iconMore { |  | ||||||
|       cursor: pointer; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   :deep( .el-scrollbar__wrap ){ |  | ||||||
|     overflow-x: hidden; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| :deep( .ai-list__content--right ){ |  | ||||||
|  |  | ||||||
|   .ai-list__content--right-wrapper { |  | ||||||
|     min-height: 100%; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| :deep( .has-gutter tr ){ |  | ||||||
|   height: 40px; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| :deep( .el-table__row td ){ |  | ||||||
|   height: 68px; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // :deep( .el-table__row td .cell ){ |  | ||||||
| //   width: 240px; |  | ||||||
| //   height: 44px; |  | ||||||
| // } |  | ||||||
|  |  | ||||||
| .table-btn { |  | ||||||
|   font-size: 14px; |  | ||||||
|   color: #2266ff; |  | ||||||
|   cursor: pointer; |  | ||||||
|  |  | ||||||
|   &:nth-child(1) { |  | ||||||
|     margin-right: 16px; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .input { |  | ||||||
|   width: 100%; |  | ||||||
|   min-height: 32px; |  | ||||||
|   line-height: 32px; |  | ||||||
|   border-radius: 4px; |  | ||||||
|   border: 1px solid #d0d4dc; |  | ||||||
|   color: #666; |  | ||||||
|   display: inline-block; |  | ||||||
|   font-size: inherit; |  | ||||||
|   cursor: pointer; |  | ||||||
|  |  | ||||||
|   &:after { |  | ||||||
|     content: '请选择...'; |  | ||||||
|     color: #888888; |  | ||||||
|     padding-left: 10px; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| :deep( .media ){ |  | ||||||
|   object-fit: fill; |  | ||||||
|   width: 40px; |  | ||||||
|   height: 40px; |  | ||||||
|   vertical-align: middle; |  | ||||||
|   box-sizing: content-box; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| :deep( .AiPersonSelect ){ |  | ||||||
|   & > button { |  | ||||||
|     background: #f5f5f5; |  | ||||||
|     border-radius: 0px 2px 2px 0px; |  | ||||||
|     border: 1px solid #d0d4dc; |  | ||||||
|     color: #222222; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| :deep( .is-active ){ |  | ||||||
|   border-right: 2px solid #2266ff; |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .el-popper { |  | ||||||
|   min-width: 76px !important; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .table-left__wrapper { |  | ||||||
|   display: flex; |  | ||||||
|   align-items: center; |  | ||||||
|  |  | ||||||
|   .table-left__wrapper--text { |  | ||||||
|     display: -webkit-box; |  | ||||||
|     -webkit-box-orient: vertical; |  | ||||||
|     -webkit-line-clamp: 2; |  | ||||||
|     overflow: hidden; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .ellipsis { |  | ||||||
|     width: 170px; |  | ||||||
|     height: 24px; |  | ||||||
|     overflow: hidden; |  | ||||||
|     text-overflow: ellipsis; |  | ||||||
|     white-space: nowrap; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   img, |  | ||||||
|   video { |  | ||||||
|     margin-right: 8px; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .el-form-item__textarea { |  | ||||||
|   position: relative; |  | ||||||
|  |  | ||||||
|   .el-form-item__btn, .el-form-item__remark { |  | ||||||
|     position: absolute; |  | ||||||
|     bottom: 12px; |  | ||||||
|     left: 12px; |  | ||||||
|     line-height: 1; |  | ||||||
|     z-index: 1; |  | ||||||
|     color: #2266FF; |  | ||||||
|     font-size: 14px; |  | ||||||
|     user-select: none; |  | ||||||
|     background: #fff; |  | ||||||
|     cursor: pointer; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .el-form-item__remark { |  | ||||||
|     left: 108px; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,66 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <div class="doc-circulation ailist-wrapper"> |  | ||||||
|     <keep-alive :include="['List']"> |  | ||||||
|       <component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component> |  | ||||||
|     </keep-alive> |  | ||||||
|   </div> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   import List from './components/List' |  | ||||||
|   import Add from './components/Add' |  | ||||||
|  |  | ||||||
|   export default { |  | ||||||
|     name: 'AppVillageCode', |  | ||||||
|     label: '一村一码', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data () { |  | ||||||
|       return { |  | ||||||
|         component: 'List', |  | ||||||
|         params: {}, |  | ||||||
|         include: [] |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     components: { |  | ||||||
|       Add, |  | ||||||
|       List |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     mounted () { |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       onChange (data) { |  | ||||||
|         if (data.type === 'Add') { |  | ||||||
|           this.component = 'Add' |  | ||||||
|           this.params = data.params |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (data.type === 'list') { |  | ||||||
|           this.component = 'List' |  | ||||||
|           this.params = data.params |  | ||||||
|  |  | ||||||
|           this.$nextTick(() => { |  | ||||||
|             if (data.isRefresh) { |  | ||||||
|               this.$refs.component.getList() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss"> |  | ||||||
|   .doc-circulation { |  | ||||||
|     height: 100%; |  | ||||||
|     background: #F3F6F9; |  | ||||||
|     overflow: auto; |  | ||||||
|   } |  | ||||||
| </style> |  | ||||||
| @@ -1,119 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <ai-detail> |  | ||||||
|     <template slot="title"> |  | ||||||
|       <ai-title title="添加二维码" isShowBack isShowBottomBorder @onBackClick="cancel(false)"> |  | ||||||
|       </ai-title> |  | ||||||
|     </template> |  | ||||||
|     <template slot="content"> |  | ||||||
|       <ai-card title="基本信息"> |  | ||||||
|         <template #content> |  | ||||||
|           <el-form class="ai-form" ref="form" :model="form" label-width="110px" label-position="right"> |  | ||||||
|             <el-form-item label="地区" style="width: 100%;" prop="codeName"> |  | ||||||
|               <span style="color: #666;">{{ form.areaName }}</span> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="二维码名称" prop="codeName" :rules="[{ required: true, message: '请输入二维码名称', trigger: 'blur' }]"> |  | ||||||
|               <el-input size="small" maxlength="30" show-word-limit placeholder="请输入二维码名称" style="width: 328px;" v-model="form.codeName"></el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item style="width: 100%;" label="二维码类型" prop="type" :rules="[{ required: true, message: '请选择二维码类型', trigger: 'change' }]"> |  | ||||||
|               <el-radio-group v-model="form.type"> |  | ||||||
|                 <el-radio label="0">群二维码</el-radio> |  | ||||||
|                 <el-radio label="1">个人二维码</el-radio> |  | ||||||
|               </el-radio-group> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="上传二维码" prop="codeUrl" style="width: 100%;" :rules="[{ required: true, message: '请上传二维码', trigger: 'change' }]"> |  | ||||||
|               <ai-uploader :instance="instance" v-model="form.codeUrl" :limit="1"></ai-uploader> |  | ||||||
|             </el-form-item> |  | ||||||
|           </el-form> |  | ||||||
|         </template> |  | ||||||
|       </ai-card> |  | ||||||
|     </template> |  | ||||||
|     <template #footer> |  | ||||||
|       <el-button @click="cancel">取消</el-button> |  | ||||||
|       <el-button type="primary" @click="confirm">提交</el-button> |  | ||||||
|     </template> |  | ||||||
|   </ai-detail> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   export default { |  | ||||||
|     name: 'Add', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object, |  | ||||||
|       params: Object |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data () { |  | ||||||
|       return { |  | ||||||
|         info: {}, |  | ||||||
|         form: { |  | ||||||
|           areaId: '', |  | ||||||
|           codeName: '', |  | ||||||
|           areaName: '', |  | ||||||
|           code: '', |  | ||||||
|           codeUrl: [], |  | ||||||
|           type: '', |  | ||||||
|         }, |  | ||||||
|         id: '' |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     created () { |  | ||||||
|       if (this.params && this.params.areaId && !this.params.id) { |  | ||||||
|         this.form.areaId = this.params.areaId |  | ||||||
|         this.form.areaName = this.params.areaName |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       if (this.params && this.params.id) { |  | ||||||
|         this.id = this.params.id |  | ||||||
|         this.getInfo(this.params.id) |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       getInfo (id) { |  | ||||||
|         this.instance.post(`/app/appeveryvillagecode/queryDetailById?id=${id}`).then(res => { |  | ||||||
|           if (res.code === 0) { |  | ||||||
|             this.form = res.data |  | ||||||
|             this.form.codeUrl = [{ |  | ||||||
|               url: res.data.codeUrl |  | ||||||
|             }] |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       onClose () { |  | ||||||
|         this.form.explain = '' |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       confirm () { |  | ||||||
|         this.$refs.form.validate((valid) => { |  | ||||||
|           if (valid) { |  | ||||||
|             this.instance.post(`/app/appeveryvillagecode/addOrUpdate`, { |  | ||||||
|               ...this.form, |  | ||||||
|               codeUrl: this.form.codeUrl[0].url |  | ||||||
|             }).then(res => { |  | ||||||
|               if (res.code == 0) { |  | ||||||
|                 this.$message.success('提交成功') |  | ||||||
|                 setTimeout(() => { |  | ||||||
|                   this.cancel(true) |  | ||||||
|                 }, 600) |  | ||||||
|               } |  | ||||||
|             }) |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       cancel (isRefresh) { |  | ||||||
|         this.$emit('change', { |  | ||||||
|           type: 'list', |  | ||||||
|           isRefresh: !!isRefresh |  | ||||||
|         }) |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| </style> |  | ||||||
| @@ -1,413 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <ai-list class="villagecode"> |  | ||||||
|     <template slot="title"> |  | ||||||
|       <ai-title title="一村一码" isShowBottomBorder></ai-title> |  | ||||||
|     </template> |  | ||||||
|     <template #left> |  | ||||||
|       <div class="villagecode-left"> |  | ||||||
|         <div class="villagecode-left__title"> |  | ||||||
|           <h2>村列表</h2> |  | ||||||
|         </div> |  | ||||||
|         <div class="addressBook-left__list"> |  | ||||||
|           <div class="addressBook-left__list--title"> |  | ||||||
|             <el-input |  | ||||||
|               class="addressBook-left__list--search" |  | ||||||
|               size="mini" |  | ||||||
|               clearable |  | ||||||
|               placeholder="请输入地区名称" |  | ||||||
|               v-model="unitName" |  | ||||||
|               suffix-icon="iconfont iconSearch"> |  | ||||||
|             </el-input> |  | ||||||
|           </div> |  | ||||||
|           <el-tree |  | ||||||
|             :filter-node-method="filterNode" |  | ||||||
|             ref="tree" |  | ||||||
|             :props="defaultProps" |  | ||||||
|             node-key="id" |  | ||||||
|             :data="areaTree" |  | ||||||
|             highlight-current |  | ||||||
|             :current-node-key="search.areaId" |  | ||||||
|             :default-expanded-keys="defaultExpanded" |  | ||||||
|             :default-checked-keys="defaultChecked" |  | ||||||
|             @current-change="onTreeChange"> |  | ||||||
|           </el-tree> |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|     </template> |  | ||||||
|     <template slot="content"> |  | ||||||
|       <ai-search-bar class="search-bar"> |  | ||||||
|         <template #left> |  | ||||||
|           <el-button size="small" type="primary" :disabled="isShowAdd" icon="iconfont iconAdd" @click="toAdd('')">添加活码</el-button> |  | ||||||
|         </template> |  | ||||||
|       </ai-search-bar> |  | ||||||
|       <ai-table |  | ||||||
|         :tableData="tableData" |  | ||||||
|         :col-configs="colConfigs" |  | ||||||
|         :total="total" |  | ||||||
|         style="margin-top: 6px;" |  | ||||||
|         :current.sync="search.current" |  | ||||||
|         :size.sync="search.size" |  | ||||||
|         @getList="getList"> |  | ||||||
|         <el-table-column slot="tags" label="标签"> |  | ||||||
|           <template slot-scope="{ row }"> |  | ||||||
|             <div class="table-tags"> |  | ||||||
|               <el-tag type="info" v-for="(item, index) in row.tags" size="small" :key="index">{{ item }}</el-tag> |  | ||||||
|             </div> |  | ||||||
|           </template> |  | ||||||
|         </el-table-column> |  | ||||||
|         <el-table-column slot="options" width="180px" fixed="right" label="操作" align="center"> |  | ||||||
|           <template slot-scope="{ row }"> |  | ||||||
|             <div class="table-options"> |  | ||||||
|               <el-popover |  | ||||||
|                   placement="bottom" |  | ||||||
|                   width="160" |  | ||||||
|                   :visible-arrow="false" |  | ||||||
|                   popper-class="wechat-message__container" |  | ||||||
|                   trigger="hover"> |  | ||||||
|                 <el-button type="text" slot="reference">二维码</el-button> |  | ||||||
|                 <div style="font-size: 0;"> |  | ||||||
|                   <img class="message-info__img" :src="row.codeUrl"> |  | ||||||
|                 </div> |  | ||||||
|               </el-popover> |  | ||||||
|               <el-button type="text" @click="toAdd(row.id)">编辑</el-button> |  | ||||||
|               <el-button type="text" @click="remove(row.id)">删除</el-button> |  | ||||||
|             </div> |  | ||||||
|           </template> |  | ||||||
|         </el-table-column> |  | ||||||
|       </ai-table> |  | ||||||
|     </template> |  | ||||||
|   </ai-list> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   import { mapState } from 'vuex' |  | ||||||
|   export default { |  | ||||||
|     name: 'List', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data() { |  | ||||||
|       return { |  | ||||||
|         search: { |  | ||||||
|           current: 1, |  | ||||||
|           size: 10, |  | ||||||
|           status: 0, |  | ||||||
|           title: '', |  | ||||||
|           areaId: '' |  | ||||||
|         }, |  | ||||||
|         defaultExpanded: [], |  | ||||||
|         defaultChecked: [], |  | ||||||
|         areaTree: [], |  | ||||||
|         defaultProps: { |  | ||||||
|           children: 'children', |  | ||||||
|           label: 'name' |  | ||||||
|         }, |  | ||||||
|         currIndex: -1, |  | ||||||
|         total: 10, |  | ||||||
|         colConfigs: [ |  | ||||||
|           {prop: 'codeName', label: '名称', align: 'left'}, |  | ||||||
|           {prop: 'type', label: '二维码类型', align: 'left', format: v => v === '0' ? '群二维码' : '个人二维码'}, |  | ||||||
|           {prop: 'createUserName', label: '创建人'}, |  | ||||||
|           {prop: 'createTime', label: '创建时间'}, |  | ||||||
|           {slot: 'options', label: '操作'} |  | ||||||
|         ], |  | ||||||
|         areaName: '', |  | ||||||
|         unitName: '', |  | ||||||
|         tableData: [] |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     computed: { |  | ||||||
|       ...mapState(['user']), |  | ||||||
|  |  | ||||||
|       isShowAdd () { |  | ||||||
|         const str = this.search.areaId.substr(this.search.areaId.length - 3) |  | ||||||
|  |  | ||||||
|         return str === '000' |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     watch: { |  | ||||||
|       unitName (val) { |  | ||||||
|         this.$refs.tree.filter(val) |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     mounted() { |  | ||||||
|       this.search.areaId = this.user.info.areaId |  | ||||||
|       this.areaName = this.user.info.areaName |  | ||||||
|       this.getTree() |  | ||||||
|       this.getList() |  | ||||||
|  |  | ||||||
|       this.$nextTick(() => { |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       getList() { |  | ||||||
|         this.instance.post(`/app/appeveryvillagecode/list`, null, { |  | ||||||
|           params: { |  | ||||||
|             ...this.search |  | ||||||
|           } |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.tableData = res.data.records |  | ||||||
|             this.total = res.data.total |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       filterNode(value, data) { |  | ||||||
|         if (!value) return true |  | ||||||
|         return data.name.indexOf(value) !== -1 |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       onTreeChange (e) { |  | ||||||
|         this.search.areaId = e.id |  | ||||||
|         this.areaName = e.name |  | ||||||
|         this.search.current = 1 |  | ||||||
|  |  | ||||||
|         this.$nextTick(() => { |  | ||||||
|           this.getList() |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       getTree () { |  | ||||||
|         this.instance.post(`/admin/area/queryAllArea?id=${this.user.info.areaId}`).then(res => { |  | ||||||
|           if (res.code === 0) { |  | ||||||
|             let parent = res.data.map(v => { |  | ||||||
|               v.label = v.name |  | ||||||
|               v.children = [] |  | ||||||
|  |  | ||||||
|               return v |  | ||||||
|             }).filter(e => !e.parentid)[0] |  | ||||||
|             this.defaultExpanded = [parent.id] |  | ||||||
|             this.defaultChecked = [parent.id] |  | ||||||
|             this.search.areaId = parent.id |  | ||||||
|             this.addChild(parent, res.data) |  | ||||||
|             this.areaTree = [parent] |  | ||||||
|  |  | ||||||
|             this.$nextTick(() => { |  | ||||||
|               this.$refs.tree.setCurrentKey(parent.id) |  | ||||||
|             }) |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       addChild (parent, list) { |  | ||||||
|         for (let i = 0; i < list.length; i++) { |  | ||||||
|           if (list[i].parentId === parent.id) { |  | ||||||
|             parent.children.push(list[i]) |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (list.length > 0) { |  | ||||||
|           parent['children'].map(v => this.addChild(v, list)) |  | ||||||
|         } |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       remove(id) { |  | ||||||
|         this.$confirm('确定删除该数据?').then(() => { |  | ||||||
|           this.instance.post(`/app/appeveryvillagecode/delete?ids=${id}`).then(res => { |  | ||||||
|             if (res.code == 0) { |  | ||||||
|               this.$message.success('删除成功!') |  | ||||||
|               this.getList() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       toAdd(id) { |  | ||||||
|         this.$emit('change', { |  | ||||||
|           type: 'Add', |  | ||||||
|           params: { |  | ||||||
|             areaName: this.areaName, |  | ||||||
|             id: id || '', |  | ||||||
|             areaId: this.search.areaId |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
| .villagecode { |  | ||||||
|   .table-tags { |  | ||||||
|     .el-tag { |  | ||||||
|       margin-right: 8px; |  | ||||||
|  |  | ||||||
|       &:last-child { |  | ||||||
|         margin-right: 0; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .addressBook-left__list { |  | ||||||
|     height: calc(100% - 40px); |  | ||||||
|     padding: 8px 8px; |  | ||||||
|     overflow: auto; |  | ||||||
|  |  | ||||||
|     .addressBook-left__tags--item { |  | ||||||
|       display: flex; |  | ||||||
|       align-items: center; |  | ||||||
|       justify-content: space-between; |  | ||||||
|       height: 40px; |  | ||||||
|       padding: 0 8px 0 16px; |  | ||||||
|       color: #222222; |  | ||||||
|  |  | ||||||
|       &.addressBook-left__tags--item-active, &:hover { |  | ||||||
|         background: #E8EFFF; |  | ||||||
|         color: #2266FF; |  | ||||||
|  |  | ||||||
|         i, span { |  | ||||||
|           color: #2266FF; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       span { |  | ||||||
|         font-size: 14px; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       i { |  | ||||||
|         cursor: pointer; |  | ||||||
|         color: #8e9ebf; |  | ||||||
|         font-size: 16px; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .addressBook-left__list--title { |  | ||||||
|       display: flex; |  | ||||||
|       align-items: center; |  | ||||||
|       margin-bottom: 8px; |  | ||||||
|  |  | ||||||
|       .addressBook-left__list--search { |  | ||||||
|         flex: 1; |  | ||||||
|         :deep( input ){ |  | ||||||
|           width: 100%; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .el-button { |  | ||||||
|         width: 84px; |  | ||||||
|         flex-shrink: 1; |  | ||||||
|         margin-right: 8px; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     span { |  | ||||||
|       color: #222222; |  | ||||||
|       font-size: 14px; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     :deep( .el-tree ){ |  | ||||||
|       background: transparent; |  | ||||||
|  |  | ||||||
|       .el-tree-node__expand-icon.is-leaf { |  | ||||||
|         color: transparent!important; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .el-tree-node__content > .el-tree-node__expand-icon { |  | ||||||
|         padding: 4px; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .el-tree-node__content { |  | ||||||
|         height: 32px; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .el-tree__empty-text { |  | ||||||
|         color: #222; |  | ||||||
|         font-size: 14px; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .el-tree-node__children .el-tree-node__content { |  | ||||||
|         height: 32px; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .el-tree-node__content:hover { |  | ||||||
|         background: #E8EFFF; |  | ||||||
|         color: #222222; |  | ||||||
|         border-radius: 2px; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       .is-current > .el-tree-node__content { |  | ||||||
|         &:hover { |  | ||||||
|           background: #2266FF; |  | ||||||
|           color: #fff; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         background: #2266FF; |  | ||||||
|  |  | ||||||
|         span { |  | ||||||
|           color: #fff; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .villagecode-left { |  | ||||||
|     width: 100%; |  | ||||||
|     height: auto; |  | ||||||
|     background: #FAFAFB; |  | ||||||
|  |  | ||||||
|     .villagecode-left__title { |  | ||||||
|       display: flex; |  | ||||||
|       align-items: center; |  | ||||||
|       height: 40px; |  | ||||||
|       padding: 0 16px; |  | ||||||
|       background: #E5E5E5; |  | ||||||
|  |  | ||||||
|       h2 { |  | ||||||
|         color: #222; |  | ||||||
|         font-size: 14px; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .villagecode-left__list { |  | ||||||
|       height: calc(100% - 40px); |  | ||||||
|       padding: 8px 0; |  | ||||||
|       overflow: auto; |  | ||||||
|  |  | ||||||
|       span { |  | ||||||
|         display: block; |  | ||||||
|         height: 40px; |  | ||||||
|         line-height: 40px; |  | ||||||
|         padding: 0 24px; |  | ||||||
|         color: #222222; |  | ||||||
|         font-size: 14px; |  | ||||||
|         cursor: pointer; |  | ||||||
|         border-right: 2px solid transparent; |  | ||||||
|         background: transparent; |  | ||||||
|  |  | ||||||
|         &:hover { |  | ||||||
|           color: #2266FF; |  | ||||||
|           background: #E8EFFF; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         &.left-active { |  | ||||||
|           color: #2266FF; |  | ||||||
|           border-color: #2266FF; |  | ||||||
|           background: #E8EFFF; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   :deep( .ai-list__content--right ){ |  | ||||||
|  |  | ||||||
|     .ai-list__content--right-wrapper { |  | ||||||
|       min-height: 100%; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .message-info__img { |  | ||||||
|   font-size: 0; |  | ||||||
|   width: 144px; |  | ||||||
|   height: 144px; |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,64 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <div class="AppFormReview"> |  | ||||||
|     <keep-alive :include="['List']"> |  | ||||||
|       <component ref="component" :is="component" :permissions="permissions " @change="onChange" :params="params" :instance="instance" :dict="dict"></component> |  | ||||||
|     </keep-alive> |  | ||||||
|   </div> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   import List from './components/List' |  | ||||||
|   import Detail from './components/Detail' |  | ||||||
|  |  | ||||||
|   export default { |  | ||||||
|     name: 'AppFormReview', |  | ||||||
|     label: '网格动态', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object, |  | ||||||
|       permissions: Function |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data () { |  | ||||||
|       return { |  | ||||||
|         component: 'List', |  | ||||||
|         params: {}, |  | ||||||
|         include: [] |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     components: { |  | ||||||
|       List, |  | ||||||
|       Detail |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       onChange (data) { |  | ||||||
|         if (data.type === 'Detail') { |  | ||||||
|           this.component = 'Detail' |  | ||||||
|           this.params = data.params |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (data.type === 'List') { |  | ||||||
|           this.component = 'List' |  | ||||||
|           this.params = data.params |  | ||||||
|  |  | ||||||
|           this.$nextTick(() => { |  | ||||||
|             if (data.isRefresh) { |  | ||||||
|               this.$refs.component.getList() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss"> |  | ||||||
| .AppFormReview { |  | ||||||
|   height: 100%; |  | ||||||
|   background: #F3F6F9; |  | ||||||
|   overflow: auto; |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,154 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <ai-detail class="AppDynamicDetail"> |  | ||||||
|     <template slot="title"> |  | ||||||
|       <ai-title title="详情" isShowBack isShowBottomBorder @onBackClick="cancel(false)"> |  | ||||||
|         <template #rightBtn> |  | ||||||
|           <div class="title-btns"> |  | ||||||
|             <el-button type="primary" icon="iconfont iconRegister" @click="isShowExamine = true" v-if="info.status == 0">审核</el-button> |  | ||||||
|           </div> |  | ||||||
|         </template> |  | ||||||
|       </ai-title> |  | ||||||
|     </template> |  | ||||||
|     <template slot="content"> |  | ||||||
|       <ai-card title="基本信息"> |  | ||||||
|         <template #content> |  | ||||||
|           <ai-wrapper label-width="120px"> |  | ||||||
|             <ai-info-item label="内容" isLine :value="info.content"></ai-info-item> |  | ||||||
|             <ai-info-item label="所属网格" isLine :value="info.girdName"></ai-info-item> |  | ||||||
|             <ai-info-item label="类型" >{{dict.getLabel("wyGirdNewsType", info.type)}}</ai-info-item> |  | ||||||
|             <ai-info-item label="地址" >{{info.address}}</ai-info-item> |  | ||||||
|             <ai-info-item label="网格员姓名" :value="info.name"></ai-info-item> |  | ||||||
|             <ai-info-item label="状态" >{{dict.getLabel("auditStatus", info.status)}}</ai-info-item> |  | ||||||
|             <ai-info-item label="发布时间"  :value="info.createTime"></ai-info-item> |  | ||||||
|             <ai-info-item label="图片" isLine> |  | ||||||
|               <div class="files"> |  | ||||||
|                 <div class="file-item" v-for="(item, index) in info.files" :key="index"> |  | ||||||
|                   <img :src="item.url" v-viewer="{movable: true}"> |  | ||||||
|                 </div> |  | ||||||
|               </div> |  | ||||||
|             </ai-info-item> |  | ||||||
|           </ai-wrapper> |  | ||||||
|         </template> |  | ||||||
|       </ai-card> |  | ||||||
|       <ai-card title="审核信息" v-if="info.status != 0"> |  | ||||||
|         <template #content> |  | ||||||
|           <ai-wrapper label-width="120px"> |  | ||||||
|             <ai-info-item label="审批意见" isLine :value="info.examineOpinion"></ai-info-item> |  | ||||||
|             <ai-info-item label="审批人" :value="info.examineUserName"></ai-info-item> |  | ||||||
|             <ai-info-item label="审批时间" :value="info.examineTime"></ai-info-item> |  | ||||||
|           </ai-wrapper> |  | ||||||
|         </template> |  | ||||||
|       </ai-card> |  | ||||||
|        <ai-dialog |  | ||||||
|         :visible.sync="isShowExamine" |  | ||||||
|         width="800px" |  | ||||||
|         title="审核" |  | ||||||
|         @closed="isShowExamine=false" |  | ||||||
|         @onConfirm="handleEvent"> |  | ||||||
|         <el-form class="ai-form" label-width="120px" :model="form" ref="form"> |  | ||||||
|           <el-form-item label="是否通过" prop="status" style="width: 100%;" :rules="[{ required: true, message: '请选择是否通过' }]"> |  | ||||||
|             <el-radio-group v-model="form.status"> |  | ||||||
|               <el-radio label="1">是</el-radio> |  | ||||||
|               <el-radio label="0">否</el-radio> |  | ||||||
|             </el-radio-group> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="审批意见" prop="opinion" style="width: 100%;" > |  | ||||||
|             <el-input type="textarea" :rows="5" :maxlength="500" v-model="form.opinion" clearable placeholder="请输入审批意见" show-word-limit></el-input> |  | ||||||
|           </el-form-item> |  | ||||||
|           <!-- <el-form-item label="图片" prop="files" style="width: 100%;"> |  | ||||||
|             <ai-uploader |  | ||||||
|                 :instance="instance" |  | ||||||
|                 isShowTip |  | ||||||
|                 v-model="form.files" |  | ||||||
|                 :limit="9"> |  | ||||||
|             </ai-uploader> |  | ||||||
|           </el-form-item> --> |  | ||||||
|         </el-form> |  | ||||||
|       </ai-dialog> |  | ||||||
|     </template> |  | ||||||
|   </ai-detail> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   export default { |  | ||||||
|     name: 'Detail', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object, |  | ||||||
|       params: Object, |  | ||||||
|       moduleId: String |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data () { |  | ||||||
|       return { |  | ||||||
|         info: {}, |  | ||||||
|         id: '', |  | ||||||
|         isShowExamine: false, |  | ||||||
|         form: {status: '', opinion: ''} |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     created () { |  | ||||||
|       this.dict.load('wyGirdNewsType', 'auditStatus').then(() => { |  | ||||||
|         this.getDetail() |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       getDetail () { |  | ||||||
|         this.instance.post(`/app/appgirdnews/queryDetailById?id=${this.params.id}`).then(res => { |  | ||||||
|           if (res.code === 0) { |  | ||||||
|             this.info = res.data |  | ||||||
|             this |  | ||||||
|             this.info = { |  | ||||||
|               ...res.data |  | ||||||
|             } |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       handleEvent() { |  | ||||||
|         this.$refs.form.validate(v => { |  | ||||||
|           if (v) { |  | ||||||
|             this.instance.post(`/app/appgirdnews/examine?id=${this.params.id}&pass=${this.form.status}&opinion=${this.form.opinion}`).then(res => { |  | ||||||
|               if (res?.code == 0) { |  | ||||||
|                 this.isShowExamine = false |  | ||||||
|                 this.$message.success('审核成功!') |  | ||||||
|                 this.cancel(true) |  | ||||||
|               } |  | ||||||
|             }) |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       cancel (isRefresh) { |  | ||||||
|         this.$emit('change', { |  | ||||||
|           type: 'List', |  | ||||||
|           isRefresh: !!isRefresh |  | ||||||
|         }) |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
|   .AppDynamicDetail { |  | ||||||
|     .files { |  | ||||||
|       display: flex; |  | ||||||
|       align-items: center; |  | ||||||
|       flex-wrap: wrap; |  | ||||||
|       .file-item { |  | ||||||
|         width: 150px; |  | ||||||
|         height: 150px; |  | ||||||
|         margin: 0 20px 20px 0; |  | ||||||
|  |  | ||||||
|         img, video { |  | ||||||
|           width: 100%; |  | ||||||
|           height: 100%; |  | ||||||
|           object-fit: cover; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </style> |  | ||||||
| @@ -1,194 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <ai-list class="notice"> |  | ||||||
|     <ai-title slot="title" title="网格动态" isShowBottomBorder></ai-title> |  | ||||||
|     <template slot="content"> |  | ||||||
|       <ai-search-bar class="search-bar"> |  | ||||||
|         <template #left> |  | ||||||
|           <ai-select |  | ||||||
|             v-model="search.type" |  | ||||||
|             @change="(search.current = 1), getList()" |  | ||||||
|             placeholder="请选择类型" |  | ||||||
|             :selectList="dict.getDict('wyGirdNewsType')"> |  | ||||||
|           </ai-select> |  | ||||||
|           <ai-picker |  | ||||||
|             :instance="instance" |  | ||||||
|             :multiple="false" |  | ||||||
|             dialogTitle="选择网格" |  | ||||||
|             :ops="{ label: 'girdName' }" |  | ||||||
|             pageTitle="网格" |  | ||||||
|             action="/app/appgirdinfo/girdList" |  | ||||||
|             @pick="onGridChange"> |  | ||||||
|             <div class="userSelcet"> |  | ||||||
|               <span style="color: #606266;" v-if="search.girdId">{{ search.girdName }}</span> |  | ||||||
|               <span v-else>请选择网格</span> |  | ||||||
|               <i class="el-icon-arrow-up"  v-if="!search.girdId"></i> |  | ||||||
|               <i class="el-icon-circle-close" v-if="search.girdId" @click.stop="search.girdId = '', search.girdName = '', search.current = 1, getList()"></i> |  | ||||||
|             </div> |  | ||||||
|           </ai-picker> |  | ||||||
|         </template> |  | ||||||
|         <template #right> |  | ||||||
|           <el-input |  | ||||||
|             v-model="search.content" |  | ||||||
|             class="search-input" |  | ||||||
|             size="small" |  | ||||||
|             v-throttle="() => {search.current = 1, getList()}" |  | ||||||
|             placeholder="内容" |  | ||||||
|             clearable |  | ||||||
|             @clear="search.current = 1, search.content = '', getList()" |  | ||||||
|             suffix-icon="iconfont iconSearch"> |  | ||||||
|           </el-input> |  | ||||||
|         </template> |  | ||||||
|       </ai-search-bar> |  | ||||||
|       <ai-table |  | ||||||
|         :tableData="tableData" |  | ||||||
|         :col-configs="colConfigs" |  | ||||||
|         :total="total" |  | ||||||
|         style="margin-top: 6px;" |  | ||||||
|         :current.sync="search.current" |  | ||||||
|         :size.sync="search.size" |  | ||||||
|         @getList="getList"> |  | ||||||
|         <el-table-column slot="options" width="120px" fixed="right" label="操作" align="center"> |  | ||||||
|           <template slot-scope="{ row }"> |  | ||||||
|             <div class="table-options"> |  | ||||||
|               <el-button type="text" @click="toDetail(row.id)">详情</el-button> |  | ||||||
|             </div> |  | ||||||
|           </template> |  | ||||||
|         </el-table-column> |  | ||||||
|       </ai-table> |  | ||||||
|     </template> |  | ||||||
|   </ai-list> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   import { mapState } from 'vuex' |  | ||||||
|   export default { |  | ||||||
|     name: 'List', |  | ||||||
|  |  | ||||||
|     props: { |  | ||||||
|       instance: Function, |  | ||||||
|       dict: Object |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     data() { |  | ||||||
|       return { |  | ||||||
|         search: { |  | ||||||
|           current: 1, |  | ||||||
|           size: 10, |  | ||||||
|           content: '', |  | ||||||
|           areaId: '', |  | ||||||
|           girdId: '', |  | ||||||
|           girdName: '' |  | ||||||
|         }, |  | ||||||
|         total: 0, |  | ||||||
|         colConfigs: [ |  | ||||||
|           { prop: 'content',  label: '内容', align: 'left', width: '200px' }, |  | ||||||
|           { prop: 'girdName', label: '所属网格', align: 'center' }, |  | ||||||
|           { prop: 'type', align: 'center', label: '类型', dict:"wyGirdNewsType"}, |  | ||||||
|           { prop: 'address', label: '地址', align: 'center' }, |  | ||||||
|           { prop: 'name',  label: '网格员姓名', align: 'center' }, |  | ||||||
|           { prop: 'status', align: 'center', label: '状态', dict:"auditStatus"}, |  | ||||||
|           { prop: 'createTime', label: '发布时间', align: 'center' } |  | ||||||
|         ], |  | ||||||
|         tableData: [], |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     computed: { |  | ||||||
|       ...mapState(['user']), |  | ||||||
|  |  | ||||||
|       hideLevel () { |  | ||||||
|         return this.user.info.areaList.length || 0 |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       params () { |  | ||||||
|         return { |  | ||||||
|           ...this.search |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     created() { |  | ||||||
|       this.dict.load('wyGirdNewsType', 'auditStatus').then(() => { |  | ||||||
|         this.getList() |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     methods: { |  | ||||||
|       getList () { |  | ||||||
|         this.instance.post(`/app/appgirdnews/list`, null, { |  | ||||||
|           params: { |  | ||||||
|             ...this.search |  | ||||||
|           } |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res.code == 0) { |  | ||||||
|             this.tableData = res.data.records |  | ||||||
|             this.total = res.data.total |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       onGridChange (e) { |  | ||||||
|         if (e.length) { |  | ||||||
|           this.search.girdId = e[0].id |  | ||||||
|           this.search.girdName = e[0].girdName |  | ||||||
|           this.search.current = 1 |  | ||||||
|           this.getList() |  | ||||||
|         } |  | ||||||
|       }, |  | ||||||
|  |  | ||||||
|       toDetail(id) { |  | ||||||
|         this.$emit('change', { |  | ||||||
|           type: 'Detail', |  | ||||||
|           params: { |  | ||||||
|             id: id || '' |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
|   .userSelcet { |  | ||||||
|     display: flex; |  | ||||||
|     align-items: center; |  | ||||||
|     justify-content: space-between; |  | ||||||
|     width: 215px; |  | ||||||
|     height: 32px; |  | ||||||
|     line-height: 32px; |  | ||||||
|     border-radius: 4px; |  | ||||||
|     border: 1px solid #d0d4dc; |  | ||||||
|     overflow: hidden; |  | ||||||
|     cursor: pointer; |  | ||||||
|     transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1); |  | ||||||
|  |  | ||||||
|     &:hover { |  | ||||||
|       border-color: $placeholderColor; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     i { |  | ||||||
|       display: flex; |  | ||||||
|       position: relative; |  | ||||||
|       align-items: center; |  | ||||||
|       justify-content: center; |  | ||||||
|       width: 30px; |  | ||||||
|       height: 100%; |  | ||||||
|       line-height: 32px; |  | ||||||
|       font-size: 14px; |  | ||||||
|       text-align: center; |  | ||||||
|       color: #d0d4dc; |  | ||||||
|       transform: rotateZ(180deg); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .el-icon-circle-close:hover { |  | ||||||
|       opacity: 0.6; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     span { |  | ||||||
|       flex: 1; |  | ||||||
|       padding: 0 15px; |  | ||||||
|       font-size: 12px; |  | ||||||
|       color: $placeholderColor; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| </style> |  | ||||||
| @@ -17,9 +17,8 @@ | |||||||
|           <el-table-column slot="scoringCycle" label="周期范围" align="center"> |           <el-table-column slot="scoringCycle" label="周期范围" align="center"> | ||||||
|             <template slot-scope="{ row }"> |             <template slot-scope="{ row }"> | ||||||
|               <span v-if="row.parentRuleName == '工单处理'">-</span> |               <span v-if="row.parentRuleName == '工单处理'">-</span> | ||||||
|               <span v-if="row.parentRuleName != '工单处理' && row.numberLimit">{{row.numberLimit.length ? $dict.getLabel("integralRuleScoringCycle", row.scoringCycle) |               <span v-else>{{row.numberLimit.length ? $dict.getLabel("integralRuleScoringCycle", row.scoringCycle) | ||||||
|                     : $dict.getLabel("integralRuleScoringCycle", row.scoringCycle) + row.numberLimit + "次"}}</span> |                     : $dict.getLabel("integralRuleScoringCycle", row.scoringCycle) + row.numberLimit + "次"}}</span> | ||||||
|               <span v-if="row.parentRuleName != '工单处理' && !row.numberLimit">{{$dict.getLabel("integralRuleScoringCycle", row.scoringCycle) + "不限次"}}</span> |  | ||||||
|             </template> |             </template> | ||||||
|           </el-table-column> |           </el-table-column> | ||||||
|           <el-table-column slot="integral" label="分值" align="center"> |           <el-table-column slot="integral" label="分值" align="center"> | ||||||
|   | |||||||
| @@ -10,10 +10,6 @@ | |||||||
|               <el-input v-model="form.title" placeholder="请输入" show-word-limit maxlength="64"></el-input> |               <el-input v-model="form.title" placeholder="请输入" show-word-limit maxlength="64"></el-input> | ||||||
|             </el-form-item> |             </el-form-item> | ||||||
|  |  | ||||||
|             <el-form-item label="名额" prop="quota" style="width: 100%"> |  | ||||||
|               <el-input-number v-model="form.quota" :min="1" :max="1000" label="请输入"></el-input-number> |  | ||||||
|             </el-form-item> |  | ||||||
|  |  | ||||||
|             <el-form-item label="活动说明" style="width: 100%"> |             <el-form-item label="活动说明" style="width: 100%"> | ||||||
|               <el-input type="textarea" :rows="5" v-model="form.detail" placeholder="请输入" show-word-limit maxlength="500"></el-input> |               <el-input type="textarea" :rows="5" v-model="form.detail" placeholder="请输入" show-word-limit maxlength="500"></el-input> | ||||||
|             </el-form-item> |             </el-form-item> | ||||||
| @@ -128,7 +124,6 @@ export default { | |||||||
|     return { |     return { | ||||||
|       form: { |       form: { | ||||||
|         title: '', |         title: '', | ||||||
|         quota: 1, |  | ||||||
|         detail: '', |         detail: '', | ||||||
|         lng: '', |         lng: '', | ||||||
|         lat: '', |         lat: '', | ||||||
| @@ -149,7 +144,6 @@ export default { | |||||||
|       }, |       }, | ||||||
|       formRules: { |       formRules: { | ||||||
|         title: [{required: true, message: "请输入活动名称", trigger: "blur"}], |         title: [{required: true, message: "请输入活动名称", trigger: "blur"}], | ||||||
|         quota: [{required: true, message: "请输入名额", trigger: "blur"}], |  | ||||||
|         location: [{required: true, validator: validLocation, trigger: "blur"}], |         location: [{required: true, validator: validLocation, trigger: "blur"}], | ||||||
|         clockRange: [{required: true, message: "请输入打卡范围", trigger: "blur"}], |         clockRange: [{required: true, message: "请输入打卡范围", trigger: "blur"}], | ||||||
|         intoTime: [{required: true, message: "请选择进场打卡时间", trigger: "blur"}], |         intoTime: [{required: true, message: "请选择进场打卡时间", trigger: "blur"}], | ||||||
| @@ -191,17 +185,17 @@ export default { | |||||||
|   watch: { |   watch: { | ||||||
|     'form.intoTime': { |     'form.intoTime': { | ||||||
|       handler(val) { |       handler(val) { | ||||||
|         if (Array.isArray(val) && val.length >= 2) { |         if(val) { | ||||||
|           this.form.intoBegintime = val[0]; |           this.form.intoBegintime = val[0] | ||||||
|           this.form.intoEndtime = val[1]; |           this.form.intoEndtime = val[1] | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     'form.exitTime': { |     'form.exitTime': { | ||||||
|       handler(val) { |       handler(val) { | ||||||
|         if (Array.isArray(val) && val.length >= 2) { |         if(val) { | ||||||
|           this.form.exitBegintime = val[0]; |           this.form.exitBegintime = val[0] | ||||||
|           this.form.exitEndtime = val[1]; |           this.form.exitEndtime = val[1] | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -8,7 +8,6 @@ | |||||||
|         <template #content> |         <template #content> | ||||||
|           <ai-wrapper> |           <ai-wrapper> | ||||||
|             <ai-info-item label="活动名称" :value="info.title"></ai-info-item> |             <ai-info-item label="活动名称" :value="info.title"></ai-info-item> | ||||||
|             <ai-info-item label="名额" :value="info.quota"></ai-info-item> |  | ||||||
|             <ai-info-item label="创建人" :value="info.createUserName"></ai-info-item> |             <ai-info-item label="创建人" :value="info.createUserName"></ai-info-item> | ||||||
|             <ai-info-item label="活动说明" isLine :value="info.detail"></ai-info-item> |             <ai-info-item label="活动说明" isLine :value="info.detail"></ai-info-item> | ||||||
|             <ai-info-item label="活动图片" isLine> |             <ai-info-item label="活动图片" isLine> | ||||||
|   | |||||||
| @@ -7,26 +7,29 @@ | |||||||
|           <el-tab-pane label="方案设置"> |           <el-tab-pane label="方案设置"> | ||||||
|             <el-form ref="AddForm" :model="form" size="small" label-width="120px" :rules="rules"> |             <el-form ref="AddForm" :model="form" size="small" label-width="120px" :rules="rules"> | ||||||
|               <ai-card title="基本信息"> |               <ai-card title="基本信息"> | ||||||
|                 <div class="grid"> |                 <template #content> | ||||||
|                   <el-form-item label="项目/系统名称" prop="name" class="row"> |                   <el-form-item label="项目/系统名称" prop="name"> | ||||||
|                     <ai-input v-model="form.name"/> |                     <el-input v-model="form.name" placeholder="请输入" clearable/> | ||||||
|                   </el-form-item> |                   </el-form-item> | ||||||
|  |                   <el-row type="flex"> | ||||||
|  |                     <div class="fill"> | ||||||
|                       <el-form-item label="系统类型" prop="type"> |                       <el-form-item label="系统类型" prop="type"> | ||||||
|                     <ai-select v-model="form.type" dict="systemType" @change="form.apps = []"/> |                         <ai-select v-model="form.type" :selectList="dict.getDict('systemType')" @change="form.apps = [],handleSysTypeChange(form.type)"/> | ||||||
|                   </el-form-item> |  | ||||||
|                   <el-form-item label="库项目根路径" prop="customPath"> |  | ||||||
|                     <ai-input v-model="form.customPath"/> |  | ||||||
|                       </el-form-item> |                       </el-form-item> | ||||||
|                       <el-form-item label="更新项目路径" prop="dist"> |                       <el-form-item label="更新项目路径" prop="dist"> | ||||||
|                     <ai-input v-model="form.dist" placeholder="常填写nginx路径,下载包从这里取"/> |                         <el-input v-model="form.dist" placeholder="常填写nginx路径,下载包从这里取" clearable/> | ||||||
|                   </el-form-item> |  | ||||||
|                   <el-form-item label="版本号" prop="version"> |  | ||||||
|                     <ai-input v-model="form.version"/> |  | ||||||
|                   </el-form-item> |  | ||||||
|                   <el-form-item label="微信机器人" prop="webhook"> |  | ||||||
|                     <ai-input v-model="form.webhook"/> |  | ||||||
|                       </el-form-item> |                       </el-form-item> | ||||||
|                     </div> |                     </div> | ||||||
|  |                     <div class="fill mar-l16"> | ||||||
|  |                       <el-form-item label="库项目根路径" prop="customPath"> | ||||||
|  |                         <el-input v-model="form.customPath" placeholder="请输入" clearable/> | ||||||
|  |                       </el-form-item> | ||||||
|  |                       <el-form-item label="版本号" prop="version"> | ||||||
|  |                         <el-input v-model="form.version" placeholder="请输入" clearable/> | ||||||
|  |                       </el-form-item> | ||||||
|  |                     </div> | ||||||
|  |                   </el-row> | ||||||
|  |                 </template> | ||||||
|               </ai-card> |               </ai-card> | ||||||
|               <ai-card title="主库应用"> |               <ai-card title="主库应用"> | ||||||
|                 <template #content> |                 <template #content> | ||||||
| @@ -35,15 +38,179 @@ | |||||||
|                   <ai-empty v-else>请先选择系统类型</ai-empty> |                   <ai-empty v-else>请先选择系统类型</ai-empty> | ||||||
|                 </template> |                 </template> | ||||||
|               </ai-card> |               </ai-card> | ||||||
|               <component class="extraConfig" title="扩展设置" :is="extraConfig" v-model="form.extra" :appList="appList"/> |               <ai-card title="扩展设置"> | ||||||
|  |                 <template #right> | ||||||
|  |                   <template v-if="form.type=='web'"> | ||||||
|  |                     <ai-dialog-btn text="设置系统信息" dialogTitle="系统信息"> | ||||||
|  |                       <el-form size="small" label-width="140px"> | ||||||
|  |                         <el-form-item label="系统标题"> | ||||||
|  |                           <el-input v-model="form.sysInfo.fullTitle" placeholder="请输入..." clearable/> | ||||||
|  |                         </el-form-item> | ||||||
|  |                         <el-form-item label="favicon"> | ||||||
|  |                           <el-input v-model="form.sysInfo.favicon" placeholder="请输入..." clearable/> | ||||||
|  |                         </el-form-item> | ||||||
|  |                         <el-form-item label="logo"> | ||||||
|  |                           <el-row type="flex"> | ||||||
|  |                             <el-input v-model="form.sysInfo.logo" placeholder="请输入..." clearable/> | ||||||
|  |                             <el-input class="mar-l10" v-model="form.sysInfo.logoText" placeholder="logo文字"> | ||||||
|  |                               <template #prepend>logo文字</template> | ||||||
|  |                             </el-input> | ||||||
|  |                           </el-row> | ||||||
|  |                         </el-form-item> | ||||||
|  |                         <el-form-item label="登录页"> | ||||||
|  |                           <el-row type="flex" class="mar-b10"> | ||||||
|  |                             <el-input v-model="form.sysInfo.loginLogo" placeholder="登录页左上角logo,带/代表图片" clearable> | ||||||
|  |                               <template #prepend>左页首logo</template> | ||||||
|  |                             </el-input> | ||||||
|  |                             <el-input class="mar-l10" v-model="form.sysInfo.loginLogoText" placeholder="logo文字" clearable> | ||||||
|  |                               <template #prepend>logo文字</template> | ||||||
|  |                             </el-input> | ||||||
|  |                           </el-row> | ||||||
|  |                           <el-row type="flex"> | ||||||
|  |                             <el-input v-model="form.sysInfo.name" placeholder="左上角标题" clearable> | ||||||
|  |                               <template #prepend>左上角标题</template> | ||||||
|  |                             </el-input> | ||||||
|  |                             <el-input class="mar-l10" v-model="form.sysInfo.title" placeholder="左上角副标题" clearable> | ||||||
|  |                               <template #prepend>左上角副标题</template> | ||||||
|  |                             </el-input> | ||||||
|  |                           </el-row> | ||||||
|  |                           <el-input class="mar-t10" type="textarea" rows="5" v-model="form.sysInfo.desc" placeholder="副标题" clearable/> | ||||||
|  |                         </el-form-item> | ||||||
|  |                         <el-row type="flex"> | ||||||
|  |                           <div class="fill"> | ||||||
|  |                             <el-form-item label="版权所有"> | ||||||
|  |                               <el-input v-model="form.sysInfo.recordDesc" placeholder="请输入..." clearable/> | ||||||
|  |                             </el-form-item> | ||||||
|  |                             <el-form-item label="备案号"> | ||||||
|  |                               <el-input v-model="form.sysInfo.recordNo" placeholder="请输入..." clearable/> | ||||||
|  |                             </el-form-item> | ||||||
|  |                           </div> | ||||||
|  |                           <div class="fill"> | ||||||
|  |                             <el-form-item label="框架版本"> | ||||||
|  |                               <!--edition :版本,标准版:standard、上架版:saas 简易版(不带扫码):simple --> | ||||||
|  |                               <el-input v-model="form.sysInfo.edition" placeholder="请输入..." clearable/> | ||||||
|  |                             </el-form-item> | ||||||
|  |                             <el-form-item label="备案跳转链接"> | ||||||
|  |                               <el-input v-model="form.sysInfo.recordURL" placeholder="请输入..." clearable/> | ||||||
|  |                             </el-form-item> | ||||||
|  |                           </div> | ||||||
|  |                         </el-row> | ||||||
|  |                         <el-form-item label="可信证书"> | ||||||
|  |                           <el-input type="textarea" v-model="form.sysInfo.ssl" placeholder="请输入可信证书的html代码" clearable rows="5"/> | ||||||
|  |                         </el-form-item> | ||||||
|  |                       </el-form> | ||||||
|  |                     </ai-dialog-btn> | ||||||
|  |                   </template> | ||||||
|  |                 </template> | ||||||
|  |                 <template #content> | ||||||
|  |                   <template v-if="form.type=='mp'"> | ||||||
|  |                     <el-form-item label="小程序AppId"> | ||||||
|  |                       <el-input v-model="form.appId" clearable placeholder="小程序appId"/> | ||||||
|  |                     </el-form-item> | ||||||
|  |                     <el-form-item label="半屏小程序"> | ||||||
|  |                       <el-input v-model="form.embeddedAppIdList" clearable placeholder="如果有多个,请用英文','分割"/> | ||||||
|  |                     </el-form-item> | ||||||
|  |                     <el-form-item label="接口是否单服务"> | ||||||
|  |                       <el-checkbox v-model="form.isSingleService"/> | ||||||
|  |                     </el-form-item> | ||||||
|  |                     <el-form-item label="引导页"> | ||||||
|  |                       <el-input v-model="form.guide" placeholder="带'/'会被认为是输入的页面路径" clearable/> | ||||||
|  |                     </el-form-item> | ||||||
|  |                     <ai-title title="底部导航栏"> | ||||||
|  |                       <el-button type="text" slot="rightBtn" icon="iconfont iconAdd" @click="tabBar.list.push({})">添加</el-button> | ||||||
|  |                     </ai-title> | ||||||
|  |                     <ai-table :tableData="tabBar.list" :colConfigs="colConfigs" tableSize="mini" :isShowPagination="false" border ref="TabBar"> | ||||||
|  |                       <el-table-column slot="options" label="操作" width="260" align="center"> | ||||||
|  |                         <template slot-scope="{row,$index}"> | ||||||
|  |                           <el-row type="flex" class="tabBarOptions"> | ||||||
|  |                             <ai-dialog-btn text="更换" dialogTitle="选择应用"> | ||||||
|  |                               <ai-lib-table :meta="appList" v-model="row.id" @select="v=>handleTabbarChange(row,v)" :isShowPagination="false" v-bind="$props" | ||||||
|  |                                             :border="false"/> | ||||||
|  |                             </ai-dialog-btn> | ||||||
|  |                             <ai-dialog-btn text="编辑" dialogTitle="编辑导航栏" width="600px"> | ||||||
|  |                               <el-form-item label="名称"> | ||||||
|  |                                 <el-input v-model="row.text" placeholder="请输入" clearable/> | ||||||
|  |                               </el-form-item> | ||||||
|  |                               <el-form-item label="默认图标"> | ||||||
|  |                                 <el-input v-model="row.iconPath" placeholder="请输入" clearable/> | ||||||
|  |                               </el-form-item> | ||||||
|  |                               <el-form-item label="选中图标"> | ||||||
|  |                                 <el-input v-model="row.selectedIconPath" placeholder="请输入" clearable/> | ||||||
|  |                               </el-form-item> | ||||||
|  |                             </ai-dialog-btn> | ||||||
|  |                             <el-button type="text" @click="handleTabbarDelete($index)">删除</el-button> | ||||||
|  |                             <el-button type="text" @click="handleTabbarPosition($index,-1)" v-if="$index>0">上移</el-button> | ||||||
|  |                             <el-button type="text" @click="handleTabbarPosition($index,1)" v-if="$index<tabBar.list.length-1">下移</el-button> | ||||||
|  |                           </el-row> | ||||||
|  |                         </template> | ||||||
|  |                       </el-table-column> | ||||||
|  |                     </ai-table> | ||||||
|  |                   </template> | ||||||
|  |                   <template v-else-if="form.type=='wxwork'"> | ||||||
|  |                     <el-row type="flex"> | ||||||
|  |                       <div class="fill"> | ||||||
|  |                         <el-form-item label="接口是否单服务"> | ||||||
|  |                           <el-checkbox v-model="form.isSingleService"/> | ||||||
|  |                         </el-form-item> | ||||||
|  |                         <el-form-item label="是否启用水印"> | ||||||
|  |                           <el-checkbox v-model="form.waterMarker"/> | ||||||
|  |                         </el-form-item> | ||||||
|  |                         <el-form-item label="自定义登录"> | ||||||
|  |                           <el-checkbox v-model="form.customLogin"/> | ||||||
|  |                         </el-form-item> | ||||||
|  |                       </div> | ||||||
|  |                       <div class="fill"> | ||||||
|  |                         <el-form-item label="域名根目录(baseURL)"> | ||||||
|  |                           <el-input v-model="form.base" clearable placeholder="域名根目录"/> | ||||||
|  |                         </el-form-item> | ||||||
|  |                         <el-form-item label="默认首页"> | ||||||
|  |                           <el-input v-model="form.homePage" clearable placeholder="填写应用的文件名"/> | ||||||
|  |                         </el-form-item> | ||||||
|  |                         <el-form-item label="开启百度流量"> | ||||||
|  |                           <el-checkbox v-model="form.hmt"/> | ||||||
|  |                         </el-form-item> | ||||||
|  |                       </div> | ||||||
|  |                     </el-row> | ||||||
|  |                   </template> | ||||||
|  |                   <template v-else-if="form.type=='web'"> | ||||||
|  |                     <el-form-item label="头部导航工具栏"> | ||||||
|  |                       <el-checkbox v-model="form.downloadCenter">下载中心</el-checkbox> | ||||||
|  |                       <el-checkbox v-model="form.dv">数据大屏</el-checkbox> | ||||||
|  |                       <el-checkbox v-model="form.showTool">显示/隐藏导航栏</el-checkbox> | ||||||
|  |                       <el-checkbox v-model="form.helpDoc">帮助文档</el-checkbox> | ||||||
|  |                       <el-checkbox v-model="form.customerService">智能客服</el-checkbox> | ||||||
|  |                       <el-checkbox v-model="form.appQRCode">手机APP</el-checkbox> | ||||||
|  |                     </el-form-item> | ||||||
|  |                     <el-row type="flex"> | ||||||
|  |                       <div class="fill"> | ||||||
|  |                         <el-form-item label="接口是否单服务"> | ||||||
|  |                           <el-checkbox v-model="form.isSingleService"/> | ||||||
|  |                         </el-form-item> | ||||||
|  |                         <el-form-item label="默认首页"> | ||||||
|  |                           <el-input v-model="form.homePage" clearable placeholder="填写应用的文件名"/> | ||||||
|  |                         </el-form-item> | ||||||
|  |                         <el-form-item label="是否加载AI助手"> | ||||||
|  |                           <el-checkbox v-model="form.copilot"/> | ||||||
|  |                         </el-form-item> | ||||||
|  |                       </div> | ||||||
|  |                       <div class="fill"> | ||||||
|  |                         <el-form-item label="域名根目录"> | ||||||
|  |                           <el-input v-model="form.base" clearable placeholder="填写域名根目录(baseURL)"/> | ||||||
|  |                         </el-form-item> | ||||||
|  |                         <el-form-item label="开启百度流量"> | ||||||
|  |                           <el-checkbox v-model="form.hmt"/> | ||||||
|  |                         </el-form-item> | ||||||
|  |                       </div> | ||||||
|  |                     </el-row> | ||||||
|  |                   </template> | ||||||
|  |                 </template> | ||||||
|  |               </ai-card> | ||||||
|             </el-form> |             </el-form> | ||||||
|           </el-tab-pane> |           </el-tab-pane> | ||||||
|           <el-tab-pane label="方案应用" lazy> |           <el-tab-pane label="方案应用" lazy> | ||||||
|             <ai-lib-table :meta="appList" customData :isShowPagination="false" v-bind="$props" disabled |             <ai-lib-table :meta="appList" customData :isShowPagination="false" v-bind="$props" disabled :colConfigs="appListConfigs"> | ||||||
|                           :colConfigs="appListConfigs"> |  | ||||||
|               <template slot="options" slot-scope="{row}"> |               <template slot="options" slot-scope="{row}"> | ||||||
|                 <ai-dialog-btn text="编辑" :customFooter="false" dialogTitle="应用配置" width="500px" |                 <ai-dialog-btn text="编辑" :customFooter="false" dialogTitle="应用配置" width="500px" @onConfirm="handleAppEdit(row)"> | ||||||
|                                @onConfirm="handleAppEdit(row)"> |  | ||||||
|                   <el-form size="small" label-width="80px"> |                   <el-form size="small" label-width="80px"> | ||||||
|                     <el-form-item label="应用名称"> |                     <el-form-item label="应用名称"> | ||||||
|                       <el-input v-model="row.label" clearable placeholder="请输入应用名称"/> |                       <el-input v-model="row.label" clearable placeholder="请输入应用名称"/> | ||||||
| @@ -66,9 +233,6 @@ | |||||||
| <script> | <script> | ||||||
| import {mapActions} from "vuex" | import {mapActions} from "vuex" | ||||||
| import AiLibTable from "./AiLibTable"; | import AiLibTable from "./AiLibTable"; | ||||||
| import webConfig from "./config/webConfig.vue"; |  | ||||||
| import wxcpConfig from "./config/wxcpConfig.vue"; |  | ||||||
| import wxmpConfig from "./config/wxmpConfig.vue"; |  | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   name: "add", |   name: "add", | ||||||
| @@ -92,26 +256,41 @@ export default { | |||||||
|         return e |         return e | ||||||
|       }).filter(e => e.project != "core") || [] |       }).filter(e => e.project != "core") || [] | ||||||
|     }, |     }, | ||||||
|     extraConfig: v => ({ |  | ||||||
|       web: webConfig, |  | ||||||
|       wxwork: wxcpConfig, |  | ||||||
|       mp: wxmpConfig |  | ||||||
|     }[v.form.type]) |  | ||||||
|   }, |   }, | ||||||
|   data() { |   data() { | ||||||
|     return { |     return { | ||||||
|       form: {apps: [], type: null, customPath: "", extra: {sysInfo: {}}}, |       form: {apps: [], type: null, sysInfo: {}, customPath: ""}, | ||||||
|       rules: { |       rules: { | ||||||
|         name: {required: true, message: "请输入"}, |         name: {required: true, message: "请输入"}, | ||||||
|         type: {required: true, message: "请选择"}, |         type: {required: true, message: "请选择"}, | ||||||
|         // customPath: {required: true, message: "请输入"}, |         // customPath: {required: true, message: "请输入"}, | ||||||
|       }, |       }, | ||||||
|  |       colConfigs: [ | ||||||
|  |         {prop: 'text', label: "名称", width: 120}, | ||||||
|  |         {prop: 'pagePath', label: "应用路径"}, | ||||||
|  |         {prop: 'iconPath', label: "默认图标"}, | ||||||
|  |         {prop: 'selectedIconPath', label: "选中图标"}, | ||||||
|  |       ], | ||||||
|       appListConfigs: [ |       appListConfigs: [ | ||||||
|         {prop: 'label', label: "应用名称", render: (h, {row}) => h(row.tabbar ? 'b' : 'p', row.label + `  ${row.tabbar ? '(底部导航栏)' : ''}`)}, |         {prop: 'label', label: "应用名称", render: (h, {row}) => h(row.tabbar ? 'b' : 'p', row.label + `  ${row.tabbar ? '(底部导航栏)' : ''}`)}, | ||||||
|         {prop: 'project', label: "项目/框架"}, |         {prop: 'project', label: "项目/框架"}, | ||||||
|         {prop: 'category', label: "分类", dict: "appsCategory"}, |         {prop: 'category', label: "分类", dict: "appsCategory"}, | ||||||
|         {prop: 'name', label: "模块名"} |         {prop: 'name', label: "模块名"} | ||||||
|       ], |       ], | ||||||
|  |       tabBar: { | ||||||
|  |         color: "#666666", | ||||||
|  |         selectedColor: "#197DF0", | ||||||
|  |         backgroundColor: "#ffffff", | ||||||
|  |         list: [ | ||||||
|  |           {pagePath: "pages/AppHome/AppHome", text: "首页", iconPath: "static/TabBar/home.png", selectedIconPath: "static/TabBar/home_selected.png"}, | ||||||
|  |           {pagePath: "pages/AppModules/AppModules", text: "应用", iconPath: "static/TabBar/service.png", selectedIconPath: "static/TabBar/service_selected.png"}, | ||||||
|  |           { | ||||||
|  |             pagePath: "pages/AppEnteringVillage/AppEnteringVillage", text: "进村", | ||||||
|  |             iconPath: "static/TabBar/custom.png", selectedIconPath: "static/TabBar/custom_selected.png" | ||||||
|  |           }, | ||||||
|  |           {pagePath: "pages/AppMine/AppMine", text: "我的", iconPath: "static/TabBar/me.png", selectedIconPath: "static/TabBar/me_selected.png"} | ||||||
|  |         ] | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   methods: { |   methods: { | ||||||
| @@ -123,6 +302,7 @@ export default { | |||||||
|       }).then(res => { |       }).then(res => { | ||||||
|         if (res?.data) { |         if (res?.data) { | ||||||
|           this.form = {...this.form, ...res.data} |           this.form = {...this.form, ...res.data} | ||||||
|  |           this.handleSysTypeChange(this.form.type, this.form.extra) | ||||||
|         } |         } | ||||||
|       }) |       }) | ||||||
|     }, |     }, | ||||||
| @@ -133,9 +313,37 @@ export default { | |||||||
|     submit() { |     submit() { | ||||||
|       this.$refs.AddForm.validate(v => { |       this.$refs.AddForm.validate(v => { | ||||||
|         if (v) { |         if (v) { | ||||||
|           if (this.form.type == 'web') { |           const { | ||||||
|             this.form.extra.sysInfo.desc = JSON.parse(this.form.extra.sysInfo.desc || null) |             tabBar, | ||||||
|             this.form.extra.sysInfo.ssl = this.form.extra.sysInfo.ssl?.replace(/"/g, "'") |             form: { | ||||||
|  |               type, | ||||||
|  |               appId, | ||||||
|  |               embeddedAppIdList, | ||||||
|  |               isSingleService, | ||||||
|  |               homePage, | ||||||
|  |               hmt, | ||||||
|  |               dv, | ||||||
|  |               downloadCenter, | ||||||
|  |               showTool, | ||||||
|  |               helpDoc, | ||||||
|  |               customerService, | ||||||
|  |               sysInfo, | ||||||
|  |               appQRCode, | ||||||
|  |               customLogin, | ||||||
|  |               base, | ||||||
|  |               guide, | ||||||
|  |               copilot | ||||||
|  |             } | ||||||
|  |           } = this | ||||||
|  |           if (type == 'mp') { | ||||||
|  |             this.form.extra = {tabBar, appId, embeddedAppIdList, isSingleService, guide} | ||||||
|  |           } else if (type == 'web') { | ||||||
|  |             const {desc} = sysInfo | ||||||
|  |             sysInfo.desc = JSON.parse(desc || null) | ||||||
|  |             sysInfo.ssl = sysInfo.ssl?.replace(/"/g, "'") | ||||||
|  |             this.form.extra = {isSingleService, homePage, hmt, dv, downloadCenter, showTool, helpDoc, customerService, sysInfo, appQRCode, base, copilot} | ||||||
|  |           } else if (type == 'wxwork') { | ||||||
|  |             this.form.extra = {isSingleService, homePage, hmt, customLogin, base} | ||||||
|           } |           } | ||||||
|           this.instance.post("/node/custom/addOrUpdate", this.form).then(res => { |           this.instance.post("/node/custom/addOrUpdate", this.form).then(res => { | ||||||
|             if (res?.code == 0) { |             if (res?.code == 0) { | ||||||
| @@ -146,11 +354,34 @@ export default { | |||||||
|         } |         } | ||||||
|       }) |       }) | ||||||
|     }, |     }, | ||||||
|  |     handleSysTypeChange(v, data = {}) { | ||||||
|  |       let values = this.$copy(data) | ||||||
|  |       if (v == 'mp') { | ||||||
|  |         if (values?.tabBar) { | ||||||
|  |           this.tabBar = values.tabBar || this.tabBar | ||||||
|  |           delete values.tabBar | ||||||
|  |         } | ||||||
|  |       } else if (v == 'web') { | ||||||
|  |         if (values?.sysInfo?.desc) values.sysInfo.desc = JSON.stringify(values.sysInfo.desc) | ||||||
|  |       } | ||||||
|  |       Object.keys(values).map(e => this.$set(this.form, e, values[e])) | ||||||
|  |     }, | ||||||
|  |     handleTabbarChange(row, {name, label}) { | ||||||
|  |       row.text = label | ||||||
|  |       row.pagePath = `pages/${name}/${name}` | ||||||
|  |     }, | ||||||
|  |     handleTabbarDelete(i) { | ||||||
|  |       this.tabBar.list?.splice(i, 1) | ||||||
|  |     }, | ||||||
|     handleAppEdit(row) { |     handleAppEdit(row) { | ||||||
|       const i = this.form.appList.findIndex(e => e.id == row.id) |       const i = this.form.appList.findIndex(e => e.id == row.id) | ||||||
|       this.form.appList.splice(i, 1, row) |       this.form.appList.splice(i, 1, row) | ||||||
|     }, |     }, | ||||||
|  |     handleTabbarPosition(i, offset) { | ||||||
|  |       const row = this.tabBar.list[i] | ||||||
|  |       this.tabBar.list.splice(i, 1, this.tabBar.list[i + offset]) | ||||||
|  |       this.tabBar.list.splice(i + offset, 1, row) | ||||||
|  |     } | ||||||
|   }, |   }, | ||||||
|   created() { |   created() { | ||||||
|     this.getDetail() |     this.getDetail() | ||||||
| @@ -173,16 +404,5 @@ export default { | |||||||
|       margin-left: 0; |       margin-left: 0; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   :deep(.extraConfig) { |  | ||||||
|     .ai-card__body { |  | ||||||
|       display: grid; |  | ||||||
|       grid-template-columns: 1fr 1fr; |  | ||||||
|  |  | ||||||
|       .row { |  | ||||||
|         grid-column: span 2; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } | } | ||||||
| </style> | </style> | ||||||
|   | |||||||
| @@ -1,116 +0,0 @@ | |||||||
| <script> |  | ||||||
| export default { |  | ||||||
|   name: "webConfig", |  | ||||||
|   model: { |  | ||||||
|     prop: "form", |  | ||||||
|     event: "input" |  | ||||||
|   }, |  | ||||||
|   props: { |  | ||||||
|     form: { default: () => ({ sysInfo: {} }) }, |  | ||||||
|     title: String |  | ||||||
|   }, |  | ||||||
|   watch: { |  | ||||||
|     form: { |  | ||||||
|       handler(v) { |  | ||||||
|         this.$emit("input", v) |  | ||||||
|       }, |  | ||||||
|       deep: true |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <ai-card :title="title" class="webConfig"> |  | ||||||
|     <template #right> |  | ||||||
|       <ai-dialog-btn text="设置系统信息" dialogTitle="系统信息"> |  | ||||||
|         <el-form size="small" label-width="140px"> |  | ||||||
|           <el-form-item label="系统标题"> |  | ||||||
|             <el-input v-model="form.sysInfo.fullTitle" placeholder="请输入..." clearable /> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="favicon"> |  | ||||||
|             <el-input v-model="form.sysInfo.favicon" placeholder="请输入..." clearable /> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="logo"> |  | ||||||
|             <el-row type="flex"> |  | ||||||
|               <el-input v-model="form.sysInfo.logo" placeholder="请输入..." clearable /> |  | ||||||
|               <el-input class="mar-l10" v-model="form.sysInfo.logoText" placeholder="logo文字"> |  | ||||||
|                 <template #prepend>logo文字</template> |  | ||||||
|               </el-input> |  | ||||||
|             </el-row> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="登录页"> |  | ||||||
|             <el-row type="flex" class="mar-b10"> |  | ||||||
|               <el-input v-model="form.sysInfo.loginLogo" placeholder="登录页左上角logo,带/代表图片" clearable> |  | ||||||
|                 <template #prepend>左页首logo</template> |  | ||||||
|               </el-input> |  | ||||||
|               <el-input class="mar-l10" v-model="form.sysInfo.loginLogoText" placeholder="logo文字" clearable> |  | ||||||
|                 <template #prepend>logo文字</template> |  | ||||||
|               </el-input> |  | ||||||
|             </el-row> |  | ||||||
|             <el-row type="flex"> |  | ||||||
|               <el-input v-model="form.sysInfo.name" placeholder="左上角标题" clearable> |  | ||||||
|                 <template #prepend>左上角标题</template> |  | ||||||
|               </el-input> |  | ||||||
|               <el-input class="mar-l10" v-model="form.sysInfo.title" placeholder="左上角副标题" clearable> |  | ||||||
|                 <template #prepend>左上角副标题</template> |  | ||||||
|               </el-input> |  | ||||||
|             </el-row> |  | ||||||
|             <el-input class="mar-t10" type="textarea" rows="5" v-model="form.sysInfo.desc" placeholder="副标题" |  | ||||||
|               clearable /> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-row type="flex"> |  | ||||||
|             <div class="fill"> |  | ||||||
|               <el-form-item label="版权所有"> |  | ||||||
|                 <el-input v-model="form.sysInfo.recordDesc" placeholder="请输入..." clearable /> |  | ||||||
|               </el-form-item> |  | ||||||
|               <el-form-item label="备案号"> |  | ||||||
|                 <el-input v-model="form.sysInfo.recordNo" placeholder="请输入..." clearable /> |  | ||||||
|               </el-form-item> |  | ||||||
|             </div> |  | ||||||
|             <div class="fill"> |  | ||||||
|               <el-form-item label="框架版本"> |  | ||||||
|                 <!--edition :版本,标准版:standard、上架版:saas 简易版(不带扫码):simple --> |  | ||||||
|                 <el-input v-model="form.sysInfo.edition" placeholder="请输入..." clearable /> |  | ||||||
|               </el-form-item> |  | ||||||
|               <el-form-item label="备案跳转链接"> |  | ||||||
|                 <el-input v-model="form.sysInfo.recordURL" placeholder="请输入..." clearable /> |  | ||||||
|               </el-form-item> |  | ||||||
|             </div> |  | ||||||
|           </el-row> |  | ||||||
|           <el-form-item label="可信证书"> |  | ||||||
|             <el-input type="textarea" v-model="form.sysInfo.ssl" placeholder="请输入可信证书的html代码" clearable rows="5" /> |  | ||||||
|           </el-form-item> |  | ||||||
|         </el-form> |  | ||||||
|       </ai-dialog-btn> |  | ||||||
|     </template> |  | ||||||
|     <template #content> |  | ||||||
|       <el-form-item label="头部导航工具栏" class="row"> |  | ||||||
|         <el-checkbox v-model="form.downloadCenter">下载中心</el-checkbox> |  | ||||||
|         <el-checkbox v-model="form.dv">数据大屏</el-checkbox> |  | ||||||
|         <el-checkbox v-model="form.showTool">显示/隐藏导航栏</el-checkbox> |  | ||||||
|         <el-checkbox v-model="form.helpDoc">帮助文档</el-checkbox> |  | ||||||
|         <el-checkbox v-model="form.customerService">智能客服</el-checkbox> |  | ||||||
|         <el-checkbox v-model="form.appQRCode">手机APP</el-checkbox> |  | ||||||
|       </el-form-item> |  | ||||||
|       <el-form-item label="接口是否单服务"> |  | ||||||
|         <el-checkbox v-model="form.isSingleService" /> |  | ||||||
|       </el-form-item> |  | ||||||
|       <el-form-item label="域名根目录"> |  | ||||||
|         <el-input v-model="form.base" clearable placeholder="填写域名根目录(baseURL)" /> |  | ||||||
|       </el-form-item> |  | ||||||
|       <el-form-item label="默认首页"> |  | ||||||
|         <el-input v-model="form.homePage" clearable placeholder="填写应用的文件名" /> |  | ||||||
|       </el-form-item> |  | ||||||
|       <el-form-item label="登录页"> |  | ||||||
|         <el-input v-model="form.signPage" clearable placeholder="填写应用的文件名" /> |  | ||||||
|       </el-form-item> |  | ||||||
|       <el-form-item label="开启百度流量"> |  | ||||||
|         <el-checkbox v-model="form.hmt" /> |  | ||||||
|       </el-form-item> |  | ||||||
|       <el-form-item label="是否加载AI助手"> |  | ||||||
|         <el-checkbox v-model="form.copilot" /> |  | ||||||
|       </el-form-item> |  | ||||||
|     </template> |  | ||||||
|   </ai-card> |  | ||||||
| </template> |  | ||||||
| @@ -1,51 +0,0 @@ | |||||||
| <script> |  | ||||||
| export default { |  | ||||||
|   name: "wxcpConfig", |  | ||||||
|   model: { |  | ||||||
|     prop: "form", |  | ||||||
|     event: "input" |  | ||||||
|   }, |  | ||||||
|   props: { |  | ||||||
|     form: Object, |  | ||||||
|     title: String |  | ||||||
|   }, |  | ||||||
|   watch: { |  | ||||||
|     form: { |  | ||||||
|       handler() { |  | ||||||
|         this.$emit("input", this.form) |  | ||||||
|       }, |  | ||||||
|       deep: true |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <ai-card :title="title" class="wxcpConfig"> |  | ||||||
|     <template #content> |  | ||||||
|       <el-form-item label="默认首页"> |  | ||||||
|         <el-input v-model="form.homePage" clearable placeholder="填写应用的文件名"/> |  | ||||||
|       </el-form-item> |  | ||||||
|       <el-form-item label="域名根目录(baseURL)"> |  | ||||||
|         <el-input v-model="form.base" clearable placeholder="域名根目录"/> |  | ||||||
|       </el-form-item> |  | ||||||
|       <el-form-item label="是否启用水印"> |  | ||||||
|         <el-checkbox v-model="form.waterMarker"/> |  | ||||||
|       </el-form-item> |  | ||||||
|       <el-form-item label="接口是否单服务"> |  | ||||||
|         <el-checkbox v-model="form.isSingleService"/> |  | ||||||
|       </el-form-item> |  | ||||||
|       <el-form-item label="自定义登录"> |  | ||||||
|         <el-checkbox v-model="form.customLogin"/> |  | ||||||
|       </el-form-item> |  | ||||||
|       <el-form-item label="开启百度流量"> |  | ||||||
|         <el-checkbox v-model="form.hmt"/> |  | ||||||
|       </el-form-item> |  | ||||||
|     </template> |  | ||||||
|   </ai-card> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .wxcpConfig { |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,126 +0,0 @@ | |||||||
| <script> |  | ||||||
| import AiLibTable from "../AiLibTable.vue"; |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "wxmpConfig", |  | ||||||
|   components: {AiLibTable}, |  | ||||||
|   model: { |  | ||||||
|     prop: "form", |  | ||||||
|     event: "input" |  | ||||||
|   }, |  | ||||||
|   props: { |  | ||||||
|     form: Object, |  | ||||||
|     title: String, |  | ||||||
|     appList: {default: () => []} |  | ||||||
|   }, |  | ||||||
|   watch: { |  | ||||||
|     form: { |  | ||||||
|       handler(v) { |  | ||||||
|         this.$emit("input", v) |  | ||||||
|       }, |  | ||||||
|       deep: true |  | ||||||
|     }, |  | ||||||
|     tabBar: { |  | ||||||
|       deep: true, handler(v) { |  | ||||||
|         this.$emit("input", {...this.form, tabBar: {...v, list: v.list.filter(e => !!e.pagePath) || []}}) |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       colConfigs: [ |  | ||||||
|         {prop: 'text', label: "名称", width: 120}, |  | ||||||
|         {prop: 'pagePath', label: "应用路径"}, |  | ||||||
|         {prop: 'iconPath', label: "默认图标"}, |  | ||||||
|         {prop: 'selectedIconPath', label: "选中图标"}, |  | ||||||
|       ], |  | ||||||
|       tabBar: { |  | ||||||
|         color: "#666666", |  | ||||||
|         selectedColor: "#197DF0", |  | ||||||
|         backgroundColor: "#ffffff", |  | ||||||
|         list: [ |  | ||||||
|           {pagePath: "pages/AppHome/AppHome", text: "首页", iconPath: "static/TabBar/home.png", selectedIconPath: "static/TabBar/home_selected.png"}, |  | ||||||
|           {pagePath: "pages/AppModules/AppModules", text: "应用", iconPath: "static/TabBar/service.png", selectedIconPath: "static/TabBar/service_selected.png"}, |  | ||||||
|           { |  | ||||||
|             pagePath: "pages/AppEnteringVillage/AppEnteringVillage", text: "进村", |  | ||||||
|             iconPath: "static/TabBar/custom.png", selectedIconPath: "static/TabBar/custom_selected.png" |  | ||||||
|           }, |  | ||||||
|           {pagePath: "pages/AppMine/AppMine", text: "我的", iconPath: "static/TabBar/me.png", selectedIconPath: "static/TabBar/me_selected.png"} |  | ||||||
|         ] |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     handleTabbarChange(row, {name, label}) { |  | ||||||
|       row.text = label |  | ||||||
|       row.pagePath = `pages/${name}/${name}` |  | ||||||
|     }, |  | ||||||
|     handleTabbarDelete(i) { |  | ||||||
|       this.tabBar.list?.splice(i, 1) |  | ||||||
|     }, |  | ||||||
|     handleTabbarPosition(i, offset) { |  | ||||||
|       const row = this.tabBar.list[i] |  | ||||||
|       this.tabBar.list.splice(i, 1, this.tabBar.list[i + offset]) |  | ||||||
|       this.tabBar.list.splice(i + offset, 1, row) |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     if (this.form.tabBar?.list?.length > 0) { |  | ||||||
|       this.tabBar = this.form.tabBar |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <ai-card :title="title" class="wxmpConfig"> |  | ||||||
|     <template #content> |  | ||||||
|       <el-form-item label="小程序AppId"> |  | ||||||
|         <el-input v-model="form.appId" clearable placeholder="小程序appId"/> |  | ||||||
|       </el-form-item> |  | ||||||
|       <el-form-item label="半屏小程序"> |  | ||||||
|         <el-input v-model="form.embeddedAppIdList" clearable placeholder="如果有多个,请用英文','分割"/> |  | ||||||
|       </el-form-item> |  | ||||||
|       <el-form-item label="接口是否单服务"> |  | ||||||
|         <el-checkbox v-model="form.isSingleService"/> |  | ||||||
|       </el-form-item> |  | ||||||
|       <el-form-item label="引导页"> |  | ||||||
|         <el-input v-model="form.guide" placeholder="带'/'会被认为是输入的页面路径" clearable/> |  | ||||||
|       </el-form-item> |  | ||||||
|       <ai-title class="row" title="底部导航栏"> |  | ||||||
|         <el-button type="text" slot="rightBtn" icon="iconfont iconAdd" @click="tabBar.list.push({})">添加</el-button> |  | ||||||
|       </ai-title> |  | ||||||
|       <ai-table class="row" :tableData="tabBar.list" :colConfigs="colConfigs" tableSize="mini" :isShowPagination="false" border ref="TabBar"> |  | ||||||
|         <el-table-column slot="options" label="操作" width="260" align="center"> |  | ||||||
|           <template slot-scope="{row,$index}"> |  | ||||||
|             <el-row type="flex" class="tabBarOptions"> |  | ||||||
|               <ai-dialog-btn text="更换" dialogTitle="选择应用"> |  | ||||||
|                 <ai-lib-table :meta="appList" v-model="row.id" @select="v=>handleTabbarChange(row,v)" :isShowPagination="false" v-bind="$props" |  | ||||||
|                               :border="false"/> |  | ||||||
|               </ai-dialog-btn> |  | ||||||
|               <ai-dialog-btn text="编辑" dialogTitle="编辑导航栏" width="600px"> |  | ||||||
|                 <el-form-item label="名称"> |  | ||||||
|                   <el-input v-model="row.text" placeholder="请输入" clearable/> |  | ||||||
|                 </el-form-item> |  | ||||||
|                 <el-form-item label="默认图标"> |  | ||||||
|                   <el-input v-model="row.iconPath" placeholder="请输入" clearable/> |  | ||||||
|                 </el-form-item> |  | ||||||
|                 <el-form-item label="选中图标"> |  | ||||||
|                   <el-input v-model="row.selectedIconPath" placeholder="请输入" clearable/> |  | ||||||
|                 </el-form-item> |  | ||||||
|               </ai-dialog-btn> |  | ||||||
|               <el-button type="text" @click="handleTabbarDelete($index)">删除</el-button> |  | ||||||
|               <el-button type="text" @click="handleTabbarPosition($index,-1)" v-if="$index>0">上移</el-button> |  | ||||||
|               <el-button type="text" @click="handleTabbarPosition($index,1)" v-if="$index<tabBar.list.length-1">下移</el-button> |  | ||||||
|             </el-row> |  | ||||||
|           </template> |  | ||||||
|         </el-table-column> |  | ||||||
|       </ai-table> |  | ||||||
|     </template> |  | ||||||
|   </ai-card> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .wxmpConfig { |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -11,12 +11,6 @@ | |||||||
|             <el-form-item style="width: 100%" label="店铺名称" prop="title" :rules="[{required: true, message: '请输入店铺名称', trigger: 'blur'}]"> |             <el-form-item style="width: 100%" label="店铺名称" prop="title" :rules="[{required: true, message: '请输入店铺名称', trigger: 'blur'}]"> | ||||||
|               <el-input type="input" size="small" v-model="form.title" clearable placeholder="请输入店铺名称" :maxlength="50" show-word-limit></el-input> |               <el-input type="input" size="small" v-model="form.title" clearable placeholder="请输入店铺名称" :maxlength="50" show-word-limit></el-input> | ||||||
|             </el-form-item> |             </el-form-item> | ||||||
|             <el-form-item style="width: 50%" label="店家" prop="shopkeeper"> |  | ||||||
|               <el-input type="input" size="small" v-model="form.shopkeeper" clearable placeholder="请输入店家名字" :maxlength="10" show-word-limit></el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item style="width: 50%" label="联系电话" prop="phone" :rules="[{required: true, message: '请输入联系电话', trigger: 'blur'}]"> |  | ||||||
|               <el-input type="number" size="small" v-model="form.phone" clearable placeholder="请输入联系电话" :maxlength="11" show-word-limit></el-input> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item style="width: 100%" label="店铺类型" prop="type" :rules="[{required: true, message: '请选择店铺类型', trigger: 'change'}]"> |             <el-form-item style="width: 100%" label="店铺类型" prop="type" :rules="[{required: true, message: '请选择店铺类型', trigger: 'change'}]"> | ||||||
|               <ai-select |               <ai-select | ||||||
|                 v-model="form.type" |                 v-model="form.type" | ||||||
| @@ -233,8 +227,6 @@ | |||||||
|         isShow: false, |         isShow: false, | ||||||
|         form: { |         form: { | ||||||
|           title: '', |           title: '', | ||||||
|           shopkeeper: '', |  | ||||||
|           phone: '', |  | ||||||
|           type: '', |           type: '', | ||||||
|           serviceType: '0', |           serviceType: '0', | ||||||
|           visibleNames: '', |           visibleNames: '', | ||||||
|   | |||||||
| @@ -1,128 +0,0 @@ | |||||||
| <script> |  | ||||||
| import {mapState} from "vuex"; |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "AppAccountConfigManage", |  | ||||||
|   label: "配置管理", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       columns: [ |  | ||||||
|         {label: "序号", type: "index"}, |  | ||||||
|         {label: "账号", prop: "userName"}, |  | ||||||
|         {label: "姓名", prop: "name"}, |  | ||||||
|         {label: "角色", prop: "roleName"}, |  | ||||||
|         {label: "所属端", prop: "type", dict: "roleType", width: 120, align: 'center'}, |  | ||||||
|         {label: "状态", prop: "configStatus", dict: "configStatus", width: 120, align: 'center'}, |  | ||||||
|       ], |  | ||||||
|       tableData: [], |  | ||||||
|       page: {pageNum: 1, pageSize: 10, total: 0}, |  | ||||||
|       search: {name: ""}, |  | ||||||
|       dialog: false, |  | ||||||
|       userId: "", |  | ||||||
|       treeData: [] |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     ...mapState(['user']) |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     getTableData() { |  | ||||||
|       this.instance.post("/api/user/config/page", null, { |  | ||||||
|         params: {...this.page, ...this.search} |  | ||||||
|       }).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           this.tableData = res.data?.records |  | ||||||
|           this.page.total = res.data.total |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     getTreeData() { |  | ||||||
|       const {userId} = this |  | ||||||
|       this.instance.post("/api/siteUser/querySiteByUserId", null, {params: {userId}}).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           this.treeData = res.data |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     handleDelete(node) { |  | ||||||
|       this.$confirm("是否要删除该节点?").then(() => { |  | ||||||
|         this.instance.post("/api/siteUser/del", null, {params: {ids: node.id}}).then(res => { |  | ||||||
|           if (res?.code == '0' && res?.data != 1) { |  | ||||||
|             this.$message.success("删除成功!") |  | ||||||
|             this.getTreeData() |  | ||||||
|           } else { |  | ||||||
|             this.$message.error(res.msg) |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     createNode(data) { |  | ||||||
|       this.$prompt("请输入名称").then(({value}) => { |  | ||||||
|         const {userId} = this |  | ||||||
|         this.instance.post("/api/siteUser/add", null, {params: {name: value, parentId: data.id, userId}}).then(res => { |  | ||||||
|           if (res?.code == '0' && res?.data != 1) { |  | ||||||
|             this.$message.success("新增成功!") |  | ||||||
|             this.getTreeData() |  | ||||||
|           } else { |  | ||||||
|             this.$message.error(res.msg) |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }) |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.dict.load("roleType", "configStatus") |  | ||||||
|     this.getTableData() |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <ai-page class="AppAccountConfigManage" :title="$options.label"> |  | ||||||
|     <ai-search-bar> |  | ||||||
|       <template #right> |  | ||||||
|         <el-input size="small" placeholder="搜索账号" v-model="search.name" clearable |  | ||||||
|                   @change="page.pageNum=1, getTableData()" @getList="getTableData"/> |  | ||||||
|       </template> |  | ||||||
|     </ai-search-bar> |  | ||||||
|     <ai-table :tableData="tableData" :colConfigs="columns" :dict="dict" @getList="getTableData" |  | ||||||
|               :total="page.total" :current.sync="page.pageNum" :size.sync="page.pageSize"> |  | ||||||
|       <el-table-column slot="options" label="操作" fixed="right" align="center"> |  | ||||||
|         <template slot-scope="{row}"> |  | ||||||
|           <div class="table-options"> |  | ||||||
|             <el-button type="text" @click="dialog=true,userId=row.id">配置</el-button> |  | ||||||
|           </div> |  | ||||||
|         </template> |  | ||||||
|       </el-table-column> |  | ||||||
|     </ai-table> |  | ||||||
|     <ai-dialog v-model="dialog" title="场地配置" width="50vw" @close="userId='',getTableData()" |  | ||||||
|                @open="getTreeData" customFooter> |  | ||||||
|       <el-button class="mar-b8" type="primary" @click="createNode(treeData)">新增根节点</el-button> |  | ||||||
|       <el-tree :data="treeData" :props="{label:'name'}" default-expand-all> |  | ||||||
|         <template slot-scope="{node,data}"> |  | ||||||
|           <div class="flex" style="width: 100%"> |  | ||||||
|             <span class="fill" v-text="node.label"/> |  | ||||||
|             <el-button size="mini" type="text" @click="createNode(data)">增加子节点</el-button> |  | ||||||
|             <el-button size="mini" type="text" @click="handleDelete(data)" v-if="$isEmpty(data.children)" class="del">删除</el-button> |  | ||||||
|           </div> |  | ||||||
|         </template> |  | ||||||
|       </el-tree> |  | ||||||
|       <el-button slot="footer" @click="dialog=false,getTableData()">关闭</el-button> |  | ||||||
|     </ai-dialog> |  | ||||||
|   </ai-page> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .AppAccountConfigManage { |  | ||||||
|   height: 100%; |  | ||||||
|  |  | ||||||
|   .el-button .del { |  | ||||||
|     color: #f46; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,263 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <section class="AppAccountManage"> |  | ||||||
|     <ai-page title="账号管理"> |  | ||||||
|       <ai-area-tree :root-id="rootArea" slot="left" v-model="search.areaId" range="3" @input="page.pageNum=1,getTableData()"/> |  | ||||||
|       <ai-search-bar> |  | ||||||
|         <template #left> |  | ||||||
|           <el-button type="primary" icon="iconfont iconAdd" @click="dialog = true">添加</el-button> |  | ||||||
|           <!--            <el-button type="primary" :disabled="!ids.toString()" @click="batchAllot">功能分配</el-button>--> |  | ||||||
|         </template> |  | ||||||
|         <template #right> |  | ||||||
|           <el-input size="small" placeholder="搜索姓名、手机号" v-model="search.condition" clearable |  | ||||||
|                     @change="page.pageNum=1, getTableData()"/> |  | ||||||
|         </template> |  | ||||||
|       </ai-search-bar> |  | ||||||
|       <ai-table :tableData="tableData" :total="page.total" :current.sync="page.pageNum" :size.sync="page.pageSize" |  | ||||||
|                 @getList="getTableData" :col-configs="colConfigs" :dict="dict" @selection-change="v => ids = v.map(e => e.id)"> |  | ||||||
|         <el-table-column slot="name" label="姓名" width="180px"> |  | ||||||
|           <el-row type="flex" align="middle" slot-scope="{row}"> |  | ||||||
|             <el-image class="avatar" :src="row.avatar" :preview-src-list="[row.avatar]"> |  | ||||||
|               <el-image slot="error" src="https://cdn.cunwuyun.cn/dvcp/h5/defaultAvatar.png" alt=""/> |  | ||||||
|             </el-image> |  | ||||||
|             <div>{{ row.name }}</div> |  | ||||||
|           </el-row> |  | ||||||
|         </el-table-column> |  | ||||||
|         <el-table-column slot="options" align="center" label="操作" fixed="right" width="220px"> |  | ||||||
|           <template slot-scope="{ row }"> |  | ||||||
|             <div class="table-options"> |  | ||||||
|               <el-button type="text" @click="changeEnable(row)">{{ row.status == 1 ? '禁用' : '启用' }}</el-button> |  | ||||||
|               <el-button type="text" @click="appAllot(row)">编辑</el-button> |  | ||||||
|               <el-button type="text" @click="resetPassword(row.id)">重置密码</el-button> |  | ||||||
|               <el-button type="text" @click="handleDelete(row)">删除</el-button> |  | ||||||
|             </div> |  | ||||||
|           </template> |  | ||||||
|         </el-table-column> |  | ||||||
|       </ai-table> |  | ||||||
|     </ai-page> |  | ||||||
|     <!--添加账号、功能分配--> |  | ||||||
|     <ai-dialog :title="dialogTitle" :visible.sync="dialog" width="60vw" @open="initDialogData" |  | ||||||
|                @onConfirm="updateAccount" @closed="dialogForm = {}"> |  | ||||||
|       <el-form ref="updateAccountForm" :model="dialogForm" :rules="rules" size="small" label-width="120px" class="grid"> |  | ||||||
|         <el-form-item required label="行政区划" prop="areaId"> |  | ||||||
|           <ai-area-get v-model.trim="dialogForm.areaId" placeholder="请选择" :instance="instance"/> |  | ||||||
|         </el-form-item> |  | ||||||
|         <el-form-item required label="账号" prop="userName"> |  | ||||||
|           <el-input v-model.trim="dialogForm.userName" placeholder="请输入..." clearable :maxLength="15"/> |  | ||||||
|         </el-form-item> |  | ||||||
|         <!--        <el-form-item required label="账号密码" prop="password" v-if="!isEdit" :rules="[{ required: true, message: '请输入密码' }]">--> |  | ||||||
|         <!--          <el-input v-model.trim="dialogForm.password" placeholder="请输入密码" clearable :minlength="6"/>--> |  | ||||||
|         <!--        </el-form-item>--> |  | ||||||
|         <el-form-item required label="角色" prop="roleId"> |  | ||||||
|           <el-select placeholder="请选择角色" :value="dialogForm.roleId" filterable v-model="dialogForm.roleId" clearable> |  | ||||||
|             <el-option v-for="(op, i) in accountRoles" :key="i" :label="op.name" :value="op.id"/> |  | ||||||
|           </el-select> |  | ||||||
|         </el-form-item> |  | ||||||
|         <el-form-item required label="姓名" prop="name"> |  | ||||||
|           <el-input v-model.trim="dialogForm.name" placeholder="请输入..." clearable :maxLength="15"/> |  | ||||||
|         </el-form-item> |  | ||||||
|         <el-form-item label="手机号码" prop="phone"> |  | ||||||
|           <el-input v-model.trim="dialogForm.phone" placeholder="请输入..." clearable :maxLength="11"/> |  | ||||||
|         </el-form-item> |  | ||||||
|         <el-form-item label="身份证号" prop="idCard" :rules="[{required:true,message:'请输入身份证号'}]"> |  | ||||||
|           <ai-input v-model.trim="dialogForm.idCard" :maxLength="18"/> |  | ||||||
|         </el-form-item> |  | ||||||
|       </el-form> |  | ||||||
|     </ai-dialog> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| import {mapState} from "vuex"; |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "AppAccountManage", |  | ||||||
|   label: "账号管理", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     ...mapState(['user']), |  | ||||||
|     cascaderProps() { |  | ||||||
|       return { |  | ||||||
|         value: 'id', |  | ||||||
|         checkStrictly: true, |  | ||||||
|         emitPath: false |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     isEdit() { |  | ||||||
|       return !!this.dialogForm.id |  | ||||||
|     }, |  | ||||||
|     dialogTitle() { |  | ||||||
|       return this.isEdit ? '编辑账号' : '添加账号' |  | ||||||
|     }, |  | ||||||
|     colConfigs() { |  | ||||||
|       return [ |  | ||||||
|         // {type: 'selection', align: 'center'}, |  | ||||||
|         {label: "账号", prop: "userName"}, |  | ||||||
|         {label: "姓名", slot: "name"}, |  | ||||||
|         {label: "联系方式", prop: "phone", align: 'center'}, |  | ||||||
|         {label: "角色", prop: "roleName", align: 'center'}, |  | ||||||
|         {label: "状态", prop: "status", align: 'center', dict: "enable"}, |  | ||||||
|         {label: "认证状态", prop: "authStatus", align: 'center', dict: "authStatus"}, |  | ||||||
|         {label: "配置状态", prop: "configStatus", align: 'center', dict: "configStatus"}, |  | ||||||
|       ] |  | ||||||
|     }, |  | ||||||
|     rules() { |  | ||||||
|       return { |  | ||||||
|         userName: [{required: true, message: "请输入账号"}], |  | ||||||
|         name: [{required: true, message: "请输入姓名"}], |  | ||||||
|         password: [{required: true, message: '请输入密码'}], |  | ||||||
|         areaId: [{required: true, message: "请选择行政区划"}], |  | ||||||
|         roleId: [{required: true, message: "请选择角色"}], |  | ||||||
|         // phone: [{required: true, message: "请输入手机号码"}] |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     rootArea: v => v.user.info.areaId |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       accountRoles: [], |  | ||||||
|       page: {pageNum: 1, pageSize: 10, total: 0}, |  | ||||||
|       dialog: false, |  | ||||||
|       dialogForm: {}, |  | ||||||
|       tableData: [], |  | ||||||
|       search: {condition: ""}, |  | ||||||
|       ids: [], |  | ||||||
|       form: { |  | ||||||
|         appids: [], |  | ||||||
|         userId: '' |  | ||||||
|       }, |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     getTableData() { |  | ||||||
|       this.instance.post("/admin/user/page", null, { |  | ||||||
|         params: {...this.page, ...this.search} |  | ||||||
|       }).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           this.tableData = res.data?.records |  | ||||||
|           this.page.total = res.data.total |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     onConfirm() { |  | ||||||
|       this.$refs.form.validate((valid) => { |  | ||||||
|         if (valid) { |  | ||||||
|           this.instance.post(`/api/sysuserwxmp/addOrUpdate`, { |  | ||||||
|             ...this.form |  | ||||||
|           }).then(res => { |  | ||||||
|             if (res.code == 0) { |  | ||||||
|               this.getTableData() |  | ||||||
|               this.$message.success('提交成功!') |  | ||||||
|  |  | ||||||
|               this.getList() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     initDialogData() { |  | ||||||
|       //用于优化初始化数据 |  | ||||||
|       this.getAccountRoles() |  | ||||||
|     }, |  | ||||||
|     getAccountRoles() { |  | ||||||
|       this.accountRoles.length == 0 && this.instance.post("/admin/role/list-all").then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           this.accountRoles = res.data |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     batchAllot() { |  | ||||||
|       this.dialog = true |  | ||||||
|       this.dialogForm = {areaId: this.user.info.areaId, ids: this.ids} |  | ||||||
|     }, |  | ||||||
|     appAllot(row) { |  | ||||||
|       this.dialog = true |  | ||||||
|       this.dialogForm = JSON.parse(JSON.stringify({ |  | ||||||
|         ...row, |  | ||||||
|         areaId: row.areaId || this.user.info.areaId |  | ||||||
|       })); |  | ||||||
|     }, |  | ||||||
|     // 修改 |  | ||||||
|     updateAccount() { |  | ||||||
|       this.$refs.updateAccountForm.validate(v => { |  | ||||||
|         if (v) { |  | ||||||
|           this.instance.post("/admin/user/addOrEdit", this.dialogForm).then(res => { |  | ||||||
|             if (res?.code == 0) { |  | ||||||
|               this.dialog = false; |  | ||||||
|               this.$message.success("提交成功") |  | ||||||
|               this.getTableData(); |  | ||||||
|             } else { |  | ||||||
|               this.$message.error(res?.msg) |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     handleDelete(row) { |  | ||||||
|       const {id: ids, authStatus, configStatus} = row |  | ||||||
|       let text = "是否要删除该账号?" |  | ||||||
|       if (authStatus == 1) { |  | ||||||
|         text = configStatus == 1 ? "该账户已经认证,是否确认删除该账户?" : "该账户已经认证及配置,是否确认删除该账户?" |  | ||||||
|       } |  | ||||||
|       this.$confirm(text).then(() => { |  | ||||||
|         this.instance.post("/admin/user/del", null, { |  | ||||||
|           params: {ids} |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res?.code == 0) { |  | ||||||
|             this.getTableData(); |  | ||||||
|             this.$message.success("删除成功!"); |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }).catch(() => 0) |  | ||||||
|     }, |  | ||||||
|     changeEnable(row) { |  | ||||||
|       const {status, id} = row |  | ||||||
|       this.$confirm(`是否要${status == 1 ? '禁用' : '启用'}该账号?`).then(() => { |  | ||||||
|         this.instance.post("/api/user/update-status", null, {params: {id}}).then(res => { |  | ||||||
|           if (res?.code == 0) { |  | ||||||
|             this.$message.success(`${status == 1 ? '禁用' : '启用'}成功!`) |  | ||||||
|             this.getTableData() |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     resetPassword(id) { |  | ||||||
|       this.$confirm("是否要重置密码?").then(() => { |  | ||||||
|         this.instance.post("/api/user/resetPwd", null, {params: {id}}).then(res => { |  | ||||||
|           if (res?.code == 0) { |  | ||||||
|             this.$message.success("重置成功!") |  | ||||||
|             this.getTableData() |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }) |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.dict.load("enable", "authStatus", "configStatus") |  | ||||||
|     this.getTableData() |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
| .AppAccountManage { |  | ||||||
|   height: 100%; |  | ||||||
|  |  | ||||||
|   :deep(.avatar) { |  | ||||||
|     width: 40px; |  | ||||||
|     height: 40px; |  | ||||||
|     margin-right: 10px; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   :deep(.el-form) { |  | ||||||
|  |  | ||||||
|     .el-cascader, |  | ||||||
|     .el-select { |  | ||||||
|       width: 100%; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,43 +0,0 @@ | |||||||
| <script> |  | ||||||
| import authAdd from "./authAdd.vue"; |  | ||||||
| import authList from "./authList.vue"; |  | ||||||
| export default { |  | ||||||
|   name: "AppAuthManage", |  | ||||||
|   label: "认证审核", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     currentPage() { |  | ||||||
|       let {hash} = this.$route |  | ||||||
|       return hash == "#add" ? authAdd : authList |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   data(){ |  | ||||||
|     return { |  | ||||||
|       certificates:[ |  | ||||||
|         {label: "身份证(正面)", prop: "frontCard"}, |  | ||||||
|         {label: "身份证(反面)", prop: "reverseCard"}, |  | ||||||
|         {label: "营业执照", prop: "businessPic", permit: ["breed"]}, |  | ||||||
|         {label: "畜禽经营许可证", prop: "breedPic", permit: ["breed"]}, |  | ||||||
|         {label: "动物防疫条件许可证", prop: "prevention", permit: ["breed"]}, |  | ||||||
|         {label: "组织机构证明", prop: "orgPic", permit: ["bank", "insurance"]}, |  | ||||||
|       ] |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <section class="AppAuthManage"> |  | ||||||
|     <component :is="currentPage" v-bind="$props"/> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .AppAuthManage { |  | ||||||
|   height: 100%; |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,85 +0,0 @@ | |||||||
| <script> |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "authAdd", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     permissions: Function, |  | ||||||
|     dict: Object |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       detail: {}, |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     isAuditing: v => v.detail.auditStatus == 1 |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     back(params = {}) { |  | ||||||
|       this.$router.push(params) |  | ||||||
|     }, |  | ||||||
|     getDetail() { |  | ||||||
|       const {id} = this.$route.query |  | ||||||
|       this.instance.post("/api/user/auth/page", null, {params: {id}}).then(res => { |  | ||||||
|         if (res?.data?.records) { |  | ||||||
|           const detail = res.data.records[0] || {} |  | ||||||
|           let {picture = "{}"} = detail |  | ||||||
|           picture = JSON.parse(picture) |  | ||||||
|           this.detail = {...detail, ...picture} |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     getNeedCerts(type) { |  | ||||||
|       return this.$parent.certificates.filter(e => !e.permit || e.permit.includes(type)) |  | ||||||
|     }, |  | ||||||
|     handleAudit(auditStatus) { |  | ||||||
|       const auditLabels = { |  | ||||||
|         2: "同意通过", 3: "驳回" |  | ||||||
|       } |  | ||||||
|       this.$confirm(`是否要${auditLabels[auditStatus]}认证?`).then(() => { |  | ||||||
|         this.instance.post("/api/user/audit", null, {params:{ |  | ||||||
|             id: this.detail.id, auditStatus |  | ||||||
|           }}).then(res => { |  | ||||||
|           if (res?.code == 0) { |  | ||||||
|             this.$confirm("是否要返回列表?","提交成功").then(() => this.back()) |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }) |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.dict.load("auditStatus") |  | ||||||
|     this.getDetail() |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <ai-page title="认证材料" class="authAdd" showBack content-string="detail"> |  | ||||||
|     <el-form size="small" label-position="top" :model="detail" ref="detail"> |  | ||||||
|       <ai-card title="认证材料"> |  | ||||||
|         <div class="grid"> |  | ||||||
|           <el-form-item v-for="(op,i) in getNeedCerts(detail.type)" :key="i" v-bind="op" :rules="{required:true,message:`请上传${op.label}`,trigger:'change'}"> |  | ||||||
|             <el-image :src="detail[op.prop]" :preview-src-list="[detail[op.prop]]"/> |  | ||||||
|           </el-form-item> |  | ||||||
|         </div> |  | ||||||
|       </ai-card> |  | ||||||
|       <ai-card title="备注说明"> |  | ||||||
|         <div v-text="detail.remark"/> |  | ||||||
|       </ai-card> |  | ||||||
|     </el-form> |  | ||||||
|     <div slot="footer"> |  | ||||||
|       <template v-if="isAuditing"> |  | ||||||
|         <el-button type="primary" @click="handleAudit(2)">同意</el-button> |  | ||||||
|         <el-button type="danger" @click="handleAudit(3)">拒绝</el-button> |  | ||||||
|       </template> |  | ||||||
|       <el-button @click="back">关闭</el-button> |  | ||||||
|     </div> |  | ||||||
|   </ai-page> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .authAdd { |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,135 +0,0 @@ | |||||||
| <script> |  | ||||||
| const columns = [ |  | ||||||
|   {label: "序号", type: "index"}, |  | ||||||
|   {label: "账号", prop: "userName"}, |  | ||||||
|   {label: "姓名", prop: "name"}, |  | ||||||
|   {label: "角色", prop: "roleName"}, |  | ||||||
|   {label: "所属端", prop: "type", dict: "roleType", width: 120, align: 'center'}, |  | ||||||
|   {label: "状态", prop: "authStatus", dict: "authStatus", width: 120, align: 'center'}, |  | ||||||
|   {label: "审核状态", prop: "auditStatus", dict: "auditStatus", width: 120, align: 'center'}, |  | ||||||
| ] |  | ||||||
| export default { |  | ||||||
|   name: "authList", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       columns, |  | ||||||
|       tableData: [], |  | ||||||
|       page: {pageNum: 1, pageSize: 10, total: 0}, |  | ||||||
|       search: {name: ""}, |  | ||||||
|       dialog: false, |  | ||||||
|       form: {} |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   watch: { |  | ||||||
|     search: { |  | ||||||
|       deep: true, |  | ||||||
|       handler() { |  | ||||||
|         this.page.pageNum = 1 |  | ||||||
|         this.getTableData() |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     getTableData() { |  | ||||||
|       this.instance.post("/api/user/auth/page", null, { |  | ||||||
|         params: {...this.page, ...this.search} |  | ||||||
|       }).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           this.tableData = res.data?.records.map(e => ({...e, permit: `${e.authStatus}` + e.auditStatus})) |  | ||||||
|           this.page.total = res.data.total |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     getNeedCerts(type) { |  | ||||||
|       return this.$parent.certificates.filter(e => !e.permit || e.permit.includes(type)) |  | ||||||
|     }, |  | ||||||
|     handleConfirm() { |  | ||||||
|       this.$refs.form.validate().then(() => { |  | ||||||
|         const {id, remark} = this.form, picture = {} |  | ||||||
|         this.$parent.certificates.forEach(e => { |  | ||||||
|           picture[e.prop] = this.form[e.prop] |  | ||||||
|         }) |  | ||||||
|         this.instance.post("/api/user/savePicture", null, { |  | ||||||
|           params: { |  | ||||||
|             id, remark, picture: JSON.stringify(picture) |  | ||||||
|           } |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res?.code == '0' && res?.data != 1) { |  | ||||||
|             this.dialog = false |  | ||||||
|             this.$message.success("提交成功!") |  | ||||||
|             this.getTableData() |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     handleUploadPics(row = {}) { |  | ||||||
|       let {id, type, remark, picture = "{}"} = row |  | ||||||
|       picture = JSON.parse(picture) |  | ||||||
|       this.form = {id, type, remark, ...picture} |  | ||||||
|       this.dialog = true |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.dict.load("roleType", "authStatus", "auditStatus") |  | ||||||
|     this.getTableData() |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <ai-page class="authList" title="认证审核"> |  | ||||||
|     <ai-search-bar> |  | ||||||
|       <template #left> |  | ||||||
|         <ai-select v-model="search.authStatus" dict="authStatus" placeholder="状态"/> |  | ||||||
|         <ai-select v-model="search.auditStatus" dict="auditStatus" placeholder="审核状态"/> |  | ||||||
|       </template> |  | ||||||
|       <template #right> |  | ||||||
|         <el-input size="small" placeholder="搜索账号" v-model="search.name" clearable |  | ||||||
|                   @change="page.pageNum=1, getTableData()" @getList="getTableData"/> |  | ||||||
|       </template> |  | ||||||
|     </ai-search-bar> |  | ||||||
|     <ai-table :tableData="tableData" :colConfigs="columns" :dict="dict" @getList="getTableData" |  | ||||||
|               :total="page.total" :current.sync="page.pageNum" :size.sync="page.pageSize"> |  | ||||||
|       <el-table-column slot="options" label="操作" fixed="right" align="center"> |  | ||||||
|         <template slot-scope="{row}"> |  | ||||||
|           <div class="table-options"> |  | ||||||
|             <el-button type="text" v-if="'12'.includes(row.permit)" |  | ||||||
|                        @click="$router.push({query:{id:row.id},hash:'#add'})">查看 |  | ||||||
|             </el-button> |  | ||||||
|             <el-button class="deleteBtn" type="text" v-if="'11'.includes(row.permit)" |  | ||||||
|                        @click="$router.push({query:{id:row.id},hash:'#add'})">审核 |  | ||||||
|             </el-button> |  | ||||||
|             <el-button type="text" v-if="'00|13'.includes(row.permit)" |  | ||||||
|                        @click="handleUploadPics(row)">认证材料 |  | ||||||
|             </el-button> |  | ||||||
|           </div> |  | ||||||
|         </template> |  | ||||||
|       </el-table-column> |  | ||||||
|     </ai-table> |  | ||||||
|     <ai-dialog v-model="dialog" title="认证材料" width="60%" @close="form={}" @confirm="handleConfirm"> |  | ||||||
|       <el-form class="grid c-3" :model="form" ref="form" label-width="160px"> |  | ||||||
|         <el-form-item v-for="(op,i) in getNeedCerts(form.type)" :key="i" v-bind="op" :rules="{required:true,message:`请上传${op.label}`,trigger:'change'}"> |  | ||||||
|           <ai-uploader v-model="form[op.prop]" valueIsUrl :limit="1" :instance="instance"/> |  | ||||||
|         </el-form-item> |  | ||||||
|         <el-form-item class="row" label="备注说明" prop="remark"> |  | ||||||
|           <el-input type="textarea" :rows="2" v-model="form.remark" placeholder="备注说明具体情况"/> |  | ||||||
|         </el-form-item> |  | ||||||
|       </el-form> |  | ||||||
|     </ai-dialog> |  | ||||||
|   </ai-page> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .authList { |  | ||||||
|   height: 100%; |  | ||||||
|  |  | ||||||
|   .deleteBtn { |  | ||||||
|     color: $errorColor; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,35 +0,0 @@ | |||||||
| <script> |  | ||||||
| import add from "./add.vue"; |  | ||||||
| import list from "./list.vue"; |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "AppBreedArchive", |  | ||||||
|   label: "电子档案", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     currentPage() { |  | ||||||
|       let {hash} = this.$route |  | ||||||
|       return hash == "#add" ? add : list |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.dict.load("archiveStatus", "category", "variety", "insuranceType", "deathReason", "dataSources", "yesOrNo") |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <section class="AppBreedArchive"> |  | ||||||
|     <component :is="currentPage" v-bind="$props"/> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .AppBreedArchive { |  | ||||||
|   height: 100%; |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,182 +0,0 @@ | |||||||
| <script> |  | ||||||
| import {mapState} from "vuex" |  | ||||||
|  |  | ||||||
| const columns = { |  | ||||||
|   weightList: [ |  | ||||||
|     {label: "序号", type: "index"}, |  | ||||||
|     {label: "重量", prop: "weight"}, |  | ||||||
|     {label: "称重时间", prop: "createTime"}, |  | ||||||
|     {label: "数据来源", prop: "source", dict: "dataSources"}, |  | ||||||
|     {label: "是否变更过", prop: "isUpdate", dict: "yesOrNo"}, |  | ||||||
|   ], |  | ||||||
|   immunityList: [ |  | ||||||
|     {label: "序号", type: "index"}, |  | ||||||
|     {label: "疫苗名称", prop: "vaccineName"}, |  | ||||||
|     {label: "用药方式", prop: "method"}, |  | ||||||
|     {label: "药量(ml)", prop: "dosage"}, |  | ||||||
|     {label: "生产厂家", prop: "factory"}, |  | ||||||
|     {label: "厂家批号", prop: "batchNumber"}, |  | ||||||
|     {label: "免疫时间", prop: "immunityTime"}, |  | ||||||
|     {label: "登记时间", prop: "createTime"}, |  | ||||||
|     {label: "防疫员", prop: "userName"}, |  | ||||||
|   ], |  | ||||||
|   treatmentList: [ |  | ||||||
|     {label: "序号", type: "index"}, |  | ||||||
|     {label: "药品名称", prop: "drugName"}, |  | ||||||
|     {label: "药量(ml)", prop: "dosage"}, |  | ||||||
|     {label: "生产厂家", prop: "factory"}, |  | ||||||
|     {label: "厂家批号", prop: "batchNumber"}, |  | ||||||
|     {label: "疾病名称", prop: "diseaseName"}, |  | ||||||
|     {label: "症状", prop: "symptom"}, |  | ||||||
|     {label: "兽医", prop: "userName"}, |  | ||||||
|     {label: "治疗时间", prop: "immunityTime"}, |  | ||||||
|     {label: "登记时间", prop: "createTime"}, |  | ||||||
|   ], |  | ||||||
|   outList: [ |  | ||||||
|     {label: "序号", type: "index"}, |  | ||||||
|     {label: "养殖场", prop: "userName", format: (v, row) => `${[row.farmName, row.houseName, row.penName].join("-")}`}, |  | ||||||
|     {label: "生物芯片耳标号", prop: "biochipEarNumber"}, |  | ||||||
|     {label: "类别", prop: "category", dict: "category", width: 120}, |  | ||||||
|     {label: "品种", prop: "variety", dict: "variety", width: 120}, |  | ||||||
|     {label: "日龄(天)", prop: "age", width: 80}, |  | ||||||
|     {label: "淘汰时间", prop: "outTime"}, |  | ||||||
|     {label: "淘汰原因", prop: "reason"} |  | ||||||
|   ], |  | ||||||
|   deathList: [ |  | ||||||
|     {label: "序号", type: "index"}, |  | ||||||
|     {label: "养殖场", prop: "userName", format: (v, row) => `${[row.farmName, row.houseName, row.penName].join("-")}`}, |  | ||||||
|     {label: "生物芯片耳标号", prop: "biochipEarNumber"}, |  | ||||||
|     {label: "类别", prop: "category", dict: "category", width: 120}, |  | ||||||
|     {label: "品种", prop: "variety", dict: "variety", width: 120}, |  | ||||||
|     {label: "日龄(天)", prop: "age", width: 80}, |  | ||||||
|     {label: "死亡时间", prop: "deathTime"}, |  | ||||||
|     {label: "死亡原因", prop: "reason", dict: "deathReason", width: 80}, |  | ||||||
|     {label: "登记时间", prop: "createTime"}, |  | ||||||
|     {label: "操作人", prop: "userName", width: 100}, |  | ||||||
|   ], |  | ||||||
|   insuranceList: [ |  | ||||||
|     {label: "序号", type: "index"}, |  | ||||||
|     {label: "保险类型", prop: "insuranceType", dict: "insuranceType"}, |  | ||||||
|     {label: "保单编号", prop: "orderNo"}, |  | ||||||
|   ] |  | ||||||
| } |  | ||||||
| const forms = { |  | ||||||
|   device: [ |  | ||||||
|     {label: "当前温度", prop: "temperature"}, |  | ||||||
|     {label: "温度状态", prop: "temperatureStatus", dict: "temperatureStatus"}, |  | ||||||
|     {label: "运动状态", prop: "sportsSituation", dict: "sportsSituation"}, |  | ||||||
|     {label: "在栏状态", prop: "status", dict: "archiveStatus"}, |  | ||||||
|   ], |  | ||||||
|   loan: [ |  | ||||||
|     {label: "贷款合同编号", prop: "contractNo"}, |  | ||||||
|   ] |  | ||||||
| } |  | ||||||
| const navs = [ |  | ||||||
|   {label: "体重记录", value: "weightList"}, |  | ||||||
|   {label: "免疫记录", value: "immunityList"}, |  | ||||||
|   {label: "治疗记录", value: "treatmentList"}, |  | ||||||
|   {label: "淘汰记录", value: "outList"}, |  | ||||||
|   {label: "死亡记录", value: "deathList"}, |  | ||||||
|   {label: "设备检测", value: "device"}, |  | ||||||
|   {label: "贷款信息", value: "loan"}, |  | ||||||
|   {label: "保险信息", value: "insuranceList"}, |  | ||||||
| ] |  | ||||||
| export default { |  | ||||||
|   name: "baAdd", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     permissions: Function, |  | ||||||
|     dict: Object |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       detail: {detailList: []}, |  | ||||||
|       active: "weightList", |  | ||||||
|       columns, navs, forms |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     ...mapState(["user"]), |  | ||||||
|     userinfo: v => v.user.info || {}, |  | ||||||
|     isAdd: v => !v.$route.query.id, |  | ||||||
|     isEdit: v => v.$route.query.edit == 1, |  | ||||||
|     pageTitle: v => { |  | ||||||
|       const appName = v.$parent.menuName || v.$parent.$options.label |  | ||||||
|       return v.$route.query.id ? v.isEdit ? `编辑${appName}` : `${appName}详情` : `新增${appName}` |  | ||||||
|     }, |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     back(params = {}) { |  | ||||||
|       this.$router.push(params) |  | ||||||
|     }, |  | ||||||
|     getDetail() { |  | ||||||
|       const {id} = this.$route.query |  | ||||||
|       return id && this.instance.post("/api/report/getInfo", null, {params: {biochipEarNumber: id}}).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           const detail = res.data |  | ||||||
|           Object.keys(columns).forEach(key => { |  | ||||||
|             detail[key] = detail[key] || [] |  | ||||||
|           }) |  | ||||||
|           return this.detail = {...detail} |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.dict.load("auditStatus", "category", "variety") |  | ||||||
|     this.getDetail() |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <ai-page :title="pageTitle" class="baAdd" showBack content-string="blank"> |  | ||||||
|     <el-form size="small" label-width="120px" :model="detail" ref="detail"> |  | ||||||
|       <ai-card title="基础信息"> |  | ||||||
|         <div class="grid c-3"> |  | ||||||
|           <el-form-item label="养殖户" prop="userName" class="row"> |  | ||||||
|             <b v-text="detail.userName"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="养殖场" prop="farmId"> |  | ||||||
|             <b v-text="detail.farmName"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="养殖舍" prop="houseId"> |  | ||||||
|             <b v-text="detail.houseName"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="养殖栏" prop="penId"> |  | ||||||
|             <b v-text="detail.penName"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="生物芯片耳标号" prop="penId"> |  | ||||||
|             <b v-text="detail.biochipEarNumber"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="电子耳标号" prop="penId"> |  | ||||||
|             <b v-text="detail.electronicEarNumber"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="原厂耳标号" prop="penId"> |  | ||||||
|             <b v-text="detail.originalEarNumber"/> |  | ||||||
|           </el-form-item> |  | ||||||
|         </div> |  | ||||||
|       </ai-card> |  | ||||||
|       <el-tabs type="border-card" v-model="active"> |  | ||||||
|         <el-tab-pane v-for="(nav,i) in navs" :key="i" :label="nav.label" :name="nav.value" lazy> |  | ||||||
|           <template v-if="active==nav.value"> |  | ||||||
|             <ai-table v-if="columns[nav.value]" :colConfigs="columns[nav.value]" :table-data="detail[nav.value]" :isShowPagination="!1"/> |  | ||||||
|             <el-form v-if="forms[nav.value]" size="small" class="grid" label-width="120px"> |  | ||||||
|               <el-form-item v-for="(item,i) in forms[nav.value]" :key="i" :label="item.label" :prop="item.prop"> |  | ||||||
|                 <b v-text="dict.getLabel(item.dict||'yesOrNo',detail[item.prop])"/> |  | ||||||
|               </el-form-item> |  | ||||||
|             </el-form> |  | ||||||
|           </template> |  | ||||||
|         </el-tab-pane> |  | ||||||
|       </el-tabs> |  | ||||||
|     </el-form> |  | ||||||
|     <div slot="footer"> |  | ||||||
|       <el-button @click="back">返回</el-button> |  | ||||||
|     </div> |  | ||||||
|   </ai-page> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .baAdd { |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,110 +0,0 @@ | |||||||
| <script> |  | ||||||
| import {mapState} from "vuex" |  | ||||||
|  |  | ||||||
| const columns = [ |  | ||||||
|   {label: "序号", type: "index"}, |  | ||||||
|   {label: "养殖户", prop: "userName", width: 100}, |  | ||||||
|   {label: "养殖场", format: (v, row) => `${[row.farmName, row.houseName, row.penName].join("-")}`, minWidth: 200}, |  | ||||||
|   {label: "生物芯片耳标号", prop: "biochipEarNumber"}, |  | ||||||
|   {label: "电子耳标号", prop: "biochipEarNumber"}, |  | ||||||
|   {label: "原厂耳标号", prop: "biochipEarNumber"}, |  | ||||||
|   {label: "入栏日期", prop: "createTime", width: 160}, |  | ||||||
|   {label: "饲养时长(天)", prop: "days", width: 100, align: 'right', headerAlign: 'center'}, |  | ||||||
|   {label: "最新体重(公斤)", prop: "weight", width: 120, align: 'right', headerAlign: 'center'}, |  | ||||||
|   // {label: "当前体温", prop: "temperatureStatus", dict: 'temperatureStatus'}, |  | ||||||
|   // {label: "运动情况", prop: "sportsSituation", dict: "sportsSituation"}, |  | ||||||
| ] |  | ||||||
| export default { |  | ||||||
|   name: "baList", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       columns, |  | ||||||
|       tableData: [], |  | ||||||
|       page: {pageNum: 1, pageSize: 10, total: 0}, |  | ||||||
|       search: {}, |  | ||||||
|       dialog: false, |  | ||||||
|       form: {} |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     ...mapState(['user']), |  | ||||||
|     userinfo: v => v.user.info || {}, |  | ||||||
|     pageTitle: v => v.$parent.menuName || v.$parent.$options.label |  | ||||||
|   }, |  | ||||||
|   watch: { |  | ||||||
|     search: { |  | ||||||
|       deep: true, |  | ||||||
|       handler() { |  | ||||||
|         this.page.pageNum = 1 |  | ||||||
|         this.getTableData() |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     getTableData() { |  | ||||||
|       this.instance.post("/api/report/getArchivePage", {...this.page, ...this.search}).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           this.tableData = res.data?.records |  | ||||||
|           this.page.total = res.data.total |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.getTableData() |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <ai-page class="baList" :title="pageTitle"> |  | ||||||
|     <ai-search-bar> |  | ||||||
|       <template #left> |  | ||||||
|         <ai-select placeholder="全部养殖户" v-model="search.userId" :instance="instance" :action="`/api/report/getOrgList`" :prop="{label:'name'}" readonly/> |  | ||||||
|         <ai-select placeholder="全部养殖场" v-model="search.farmId" :instance="instance" :action="`/api/siteUser/querySiteByUserId?userId=${search.userId||''}`" :prop="{label:'name'}"/> |  | ||||||
|         <ai-select placeholder="全部养殖舍" v-model="search.houseId" :instance="instance" :action="`/api/siteUser/querySiteById?id=${search.farmId||-1}`" :prop="{label:'name'}"/> |  | ||||||
|         <ai-select placeholder="全部养殖栏" v-model="search.penId" :instance="instance" :action="`/api/siteUser/querySiteById?id=${search.houseId||-1}`" :prop="{label:'name'}"/> |  | ||||||
|         <ai-input placeholder="生物芯片耳标号" v-model="search.biochipEarNumber"/> |  | ||||||
|         <ai-input placeholder="电子耳标号" v-model="search.electronicEarNumber"/> |  | ||||||
|         <ai-input placeholder="原厂耳标号" v-model="search.originalEarNumber"/> |  | ||||||
|         <ai-select placeholder="全部状态" v-model="search.status" dict="archiveStatus"/> |  | ||||||
|         <ai-select placeholder="全部类别" v-model="search.category" dict="category"/> |  | ||||||
|         <ai-select placeholder="全部品种" v-model="search.variety" dict="variety"/> |  | ||||||
|         <ai-search label="入栏日期"> |  | ||||||
|           <el-date-picker value-format="yyyy-MM-dd HH:mm:ss" v-model="search.beginDate" type="datetime" placeholder="开始日期" size="small"/> |  | ||||||
|           <el-date-picker value-format="yyyy-MM-dd HH:mm:ss" v-model="search.endDate" type="datetime" placeholder="结束日期" size="small"/> |  | ||||||
|         </ai-search> |  | ||||||
|       </template> |  | ||||||
|     </ai-search-bar> |  | ||||||
|     <ai-search-bar> |  | ||||||
|       <template #left> |  | ||||||
|         <ai-download :instance="instance" url="/api/report/exportArchive" :params="{...search,...page}" :fileName="`${pageTitle}导出表-${Date.now()}`"/> |  | ||||||
|       </template> |  | ||||||
|     </ai-search-bar> |  | ||||||
|     <ai-table :tableData="tableData" :colConfigs="columns" :dict="dict" @getList="getTableData" |  | ||||||
|               :total="page.total" :current.sync="page.pageNum" :size.sync="page.pageSize"> |  | ||||||
|       <el-table-column slot="options" label="操作" fixed="right" align="center"> |  | ||||||
|         <template slot-scope="{row}"> |  | ||||||
|           <div class="table-options"> |  | ||||||
|             <el-button type="text" @click="$router.push({hash:'#add',query:{id:row.biochipEarNumber}})">查看</el-button> |  | ||||||
|           </div> |  | ||||||
|         </template> |  | ||||||
|       </el-table-column> |  | ||||||
|     </ai-table> |  | ||||||
|   </ai-page> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .baList { |  | ||||||
|   height: 100%; |  | ||||||
|  |  | ||||||
|   .deleteBtn { |  | ||||||
|     color: $errorColor; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,35 +0,0 @@ | |||||||
| <script> |  | ||||||
| import add from "./add.vue"; |  | ||||||
| import list from "./list.vue"; |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "AppClaimApply", |  | ||||||
|   label: "理赔申请", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     currentPage() { |  | ||||||
|       let {hash} = this.$route |  | ||||||
|       return ["#claim", "#add"].includes(hash) ? add : list |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.dict.load("auditStatus", "insureType", "insureStatus", "category", "variety") |  | ||||||
|   }, |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <section class="AppClaimApply"> |  | ||||||
|     <component :is="currentPage" v-bind="$props"/> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .AppClaimApply { |  | ||||||
|   height: 100%; |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,145 +0,0 @@ | |||||||
| <script> |  | ||||||
| import {mapState} from "vuex" |  | ||||||
| import AiEartagPicker from "@project/xumu/components/AiEartagPicker.vue"; |  | ||||||
|  |  | ||||||
| const records = [ |  | ||||||
|   {label: "序号", type: "index"}, |  | ||||||
|   {label: "报案号", prop: "reportNo"}, |  | ||||||
|   {label: "审批状态", prop: "auditStatus", dict: "auditStatus"}, |  | ||||||
|   {label: "审批时间", prop: "auditTime"}, |  | ||||||
|   {label: "审批人", prop: "auditName"}, |  | ||||||
| ] |  | ||||||
| export default { |  | ||||||
|   name: "claimAdd", |  | ||||||
|   components: {AiEartagPicker}, |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     permissions: Function, |  | ||||||
|     dict: Object |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       detail: {detailList: []}, |  | ||||||
|       records |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     ...mapState(["user"]), |  | ||||||
|     userinfo: v => v.user.info || {}, |  | ||||||
|     pageTitle: v => { |  | ||||||
|       const appName = v.$parent.menuName || v.$parent.$options.label |  | ||||||
|       return v.isClaim ? `新增${appName}` : `${appName}详情` |  | ||||||
|     }, |  | ||||||
|     isClaim: v => v.$route.hash == "#claim", |  | ||||||
|     formImages: v => [ |  | ||||||
|       {label: "勘察报告书", prop: "surveyPicture", rules: {required: v.isClaim, message: '请上传 勘察报告书'}}, |  | ||||||
|       {label: "无害化回执单", prop: "receiptPicture", rules: {required: v.isClaim, message: '请上传 无害化回执单'}}, |  | ||||||
|     ], |  | ||||||
|     columns: v => [ |  | ||||||
|       {label: "序号", type: "index"}, |  | ||||||
|       {label: "生物芯片耳标号", prop: "biochipEarNumber"}, |  | ||||||
|       {label: "身长测量照片", prop: "heightPicture", upload: {instance: v.instance, readonly: !v.isClaim, valueIsUrl: !0, limit: 1}}, |  | ||||||
|       {label: "电子耳标照片", prop: "earNumberPicture", upload: {instance: v.instance, readonly: !v.isClaim, valueIsUrl: !0, limit: 1}}, |  | ||||||
|       {label: "防疫耳标照片", prop: "preventionPicture", upload: {instance: v.instance, readonly: !v.isClaim, valueIsUrl: !0, limit: 1}}, |  | ||||||
|       {label: "无害化处理照片", prop: "harmlessPicture", upload: {instance: v.instance, readonly: !v.isClaim, valueIsUrl: !0, limit: 1}}, |  | ||||||
|       {label: "报案号", prop: "reportNo", hide: v.isClaim}, |  | ||||||
|     ].filter(e => !e.hide), |  | ||||||
|     selectedEartags: v => v.detail.list?.length || 0, |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     back(params = {}) { |  | ||||||
|       this.$router.push(params) |  | ||||||
|     }, |  | ||||||
|     getDetail() { |  | ||||||
|       const {id} = this.$route.query |  | ||||||
|       return id && this.instance.post("/api/insurance/claim/apply/getInfo", null, {params: {orderNo: id}}).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           const detail = res.data |  | ||||||
|           return this.detail = {...detail} |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     submit() { |  | ||||||
|       this.$refs.detail.validate().then(() => { |  | ||||||
|         this.instance.post("/api/insurance/claim/apply/add", {...this.detail}).then(res => { |  | ||||||
|           if (res?.code == '0') { |  | ||||||
|             this.$message.success("提交成功!") |  | ||||||
|             this.back() |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }) |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.getDetail() |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <ai-page :title="pageTitle" class="claimAdd" showBack content-string="blank"> |  | ||||||
|     <el-form size="small" label-width="120px" :model="detail" ref="detail"> |  | ||||||
|       <ai-card title="基础信息"> |  | ||||||
|         <div class="grid"> |  | ||||||
|           <el-form-item label="养殖场" prop="farmId"> |  | ||||||
|             <b v-text="detail.farmName"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="承保公司" prop="companyId"> |  | ||||||
|             <b v-text="detail.companyName"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="投保类型"> |  | ||||||
|             <ai-input :value="dict.getLabel('insureType',detail.insureType)" :edit="!1"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="保险产品" prop="productType"> |  | ||||||
|             <b v-text="detail.productType"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="联系人"> |  | ||||||
|             <ai-input v-model="detail.contacts" :edit="!1"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="联系电话"> |  | ||||||
|             <ai-input v-model="detail.phone" :edit="!1"/> |  | ||||||
|           </el-form-item> |  | ||||||
|         </div> |  | ||||||
|       </ai-card> |  | ||||||
|       <ai-card title="投保对象"> |  | ||||||
|         <template #right v-if="isClaim"> |  | ||||||
|           <ai-eartag-picker @select="v=>detail.detailList=v" :instance="instance" |  | ||||||
|                             :action="`/api/insurance/claim/apply/getClaimEarNumberList?orderNo=${detail.orderNo}`"> |  | ||||||
|             <el-button type="text">选择</el-button> |  | ||||||
|           </ai-eartag-picker> |  | ||||||
|         </template> |  | ||||||
|         <ai-highlight class="mar-b8 font-14" :content="`投保标的共${detail.insureNumber||0}只,已理赔标的共 @v 只`" color="red" :value="selectedEartags"/> |  | ||||||
|         <ai-table :tableData="detail.detailList" :colConfigs="columns" :isShowPagination="!1" hideOptions/> |  | ||||||
|       </ai-card> |  | ||||||
|       <ai-card title="理赔材料" v-if="isClaim"> |  | ||||||
|         <div class="font-12 mar-b8">只能上传JPG/PNG文件,且不超过2M,一次最多5张</div> |  | ||||||
|         <el-form-item v-for="(img,i) in formImages" :key="i" v-bind="img"> |  | ||||||
|           <ai-uploader v-model="detail[img.prop]" :instance="instance" value-is-url :limit="5"/> |  | ||||||
|         </el-form-item> |  | ||||||
|       </ai-card> |  | ||||||
|       <ai-card title="理赔记录" v-else> |  | ||||||
|         <ai-table :tableData="detail.list" :colConfigs="records" :isShowPagination="!1" hideOptions/> |  | ||||||
|       </ai-card> |  | ||||||
|     </el-form> |  | ||||||
|     <div slot="footer"> |  | ||||||
|       <template v-if="isClaim"> |  | ||||||
|         <el-button type="primary" @click="submit(1)">提交</el-button> |  | ||||||
|       </template> |  | ||||||
|       <el-button @click="back">返回</el-button> |  | ||||||
|     </div> |  | ||||||
|   </ai-page> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .claimAdd { |  | ||||||
|   :deep(.el-form--label-top) { |  | ||||||
|     .el-form-item__label { |  | ||||||
|       width: 100% !important; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .el-form-item__content { |  | ||||||
|       margin-left: unset !important; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,123 +0,0 @@ | |||||||
| <script> |  | ||||||
| import {mapState} from "vuex" |  | ||||||
|  |  | ||||||
| const columns = [ |  | ||||||
|   {label: "序号", type: "index"}, |  | ||||||
|   {label: "投保单号", prop: "orderNo"}, |  | ||||||
|   {label: "所属养殖户", prop: "applyName"}, |  | ||||||
|   {label: "所属养殖场", prop: "farmName"}, |  | ||||||
|   {label: "投保数量(头)", prop: "insureNumber", width: 120}, |  | ||||||
|   {label: "投保状态", prop: "status", width: 160, dict: "insureStatus"}, |  | ||||||
|   {label: "投保类型", prop: "insureType", dict: "insureType"}, |  | ||||||
|   {label: "投保时间", prop: "createTime"}, |  | ||||||
|   {label: "可理赔数量", prop: "unpaidClaimNumber", width: 120}, |  | ||||||
|   {label: "说明", prop: "remarks"}, |  | ||||||
| ] |  | ||||||
| export default { |  | ||||||
|   name: "claimList", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       columns, |  | ||||||
|       tableData: [], |  | ||||||
|       page: {pageNum: 1, pageSize: 10, total: 0}, |  | ||||||
|       search: {}, |  | ||||||
|       dialog: false, |  | ||||||
|       form: {} |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     ...mapState(['user']), |  | ||||||
|     userinfo: v => v.user.info || {}, |  | ||||||
|     pageTitle: v => v.$parent.menuName || v.$parent.$options.label |  | ||||||
|   }, |  | ||||||
|   watch: { |  | ||||||
|     search: { |  | ||||||
|       deep: true, |  | ||||||
|       handler() { |  | ||||||
|         this.page.pageNum = 1 |  | ||||||
|         this.getTableData() |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     getTableData() { |  | ||||||
|       this.instance.post("/api/insurance/claim/apply/page", {...this.page, ...this.search}).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           this.tableData = res.data?.records.map(e => ({...e, permit: e.remarks == "可申请理赔"})) |  | ||||||
|           this.page.total = res.data.total |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.getTableData() |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <ai-page class="claimList" :title="pageTitle"> |  | ||||||
|     <ai-search-bar> |  | ||||||
|       <template #left> |  | ||||||
|         <ai-input placeholder="投保订单号" v-model="search.orderNo"/> |  | ||||||
|         <ai-select placeholder="全部投保类型" v-model="search.insureType" dict="insureType"/> |  | ||||||
|         <ai-search label="投保日期"> |  | ||||||
|           <el-date-picker value-format="yyyy-MM-dd HH:mm:ss" v-model="search.beginDate" type="datetime" placeholder="开始日期" size="small"/> |  | ||||||
|           <el-date-picker value-format="yyyy-MM-dd HH:mm:ss" v-model="search.endDate" type="datetime" placeholder="结束日期" size="small"/> |  | ||||||
|         </ai-search> |  | ||||||
|         <ai-input placeholder="养殖户" v-model="search.applyName"/> |  | ||||||
|         <ai-input placeholder="养殖场" v-model="search.farmName"/> |  | ||||||
|       </template> |  | ||||||
|     </ai-search-bar> |  | ||||||
|     <ai-search-bar> |  | ||||||
|       <template #left> |  | ||||||
|         <ai-download :instance="instance" url="/api/insurance/claim/apply/export" :params="{...search,...page}" :fileName="`${pageTitle}导出表-${Date.now()}`"/> |  | ||||||
|       </template> |  | ||||||
|     </ai-search-bar> |  | ||||||
|     <ai-table :tableData="tableData" :colConfigs="columns" :dict="dict" @getList="getTableData" |  | ||||||
|               :total="page.total" :current.sync="page.pageNum" :size.sync="page.pageSize"> |  | ||||||
|       <el-table-column slot="options" label="操作" fixed="right" align="center"> |  | ||||||
|         <template slot-scope="{row}"> |  | ||||||
|           <div class="table-options"> |  | ||||||
|             <template v-if="row.permit"> |  | ||||||
|               <el-button type="text" @click="dialog=true,$set(form,'id',row.orderNo)">理赔</el-button> |  | ||||||
|             </template> |  | ||||||
|             <el-button v-else type="text" @click="$router.push({hash:'#add',query:{id:row.orderNo}})">查看</el-button> |  | ||||||
|           </div> |  | ||||||
|         </template> |  | ||||||
|       </el-table-column> |  | ||||||
|     </ai-table> |  | ||||||
|     <ai-dialog v-model="dialog" title="理赔须知" @closed="form={}"> |  | ||||||
|       <el-form size="small" label-position="top" :mode="form" ref="form"> |  | ||||||
|         <el-form-item label="如遇一下情况进行赔付:"> |  | ||||||
|           1、自然灾害:如暴雨、洪水、台风、冰雹、雷击、暴风雪等导致的肉牛死亡或伤残;<br/> |  | ||||||
|           2、疾病与疫病:包括但不限于口蹄疫、布鲁氏菌病、炭疽、牛结核病等对肉牛生命安全造成威胁的疾病;<br/> |  | ||||||
|           3、意外事故:如火灾、爆炸、触电、盗窃、走失等;<br/> |  | ||||||
|           4、强制扑杀:由于政府政策或疫情控制需要,对肉牛进行的强制扑杀。 |  | ||||||
|         </el-form-item> |  | ||||||
|         <el-form-item class="flex center"> |  | ||||||
|           <el-checkbox v-model="form.agree">本人阅读并知晓理赔须知,承认上传资料的真实性</el-checkbox> |  | ||||||
|         </el-form-item> |  | ||||||
|       </el-form> |  | ||||||
|       <template #foot> |  | ||||||
|         <el-button @click="$router.push({hash:'#claim',query:{id:form.id}})" type="primary" :disabled="!form.agree">符合要求,立即申请</el-button> |  | ||||||
|         <el-button @click="dialog=false">取消</el-button> |  | ||||||
|       </template> |  | ||||||
|     </ai-dialog> |  | ||||||
|   </ai-page> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .claimList { |  | ||||||
|   height: 100%; |  | ||||||
|  |  | ||||||
|   .deleteBtn { |  | ||||||
|     color: $errorColor; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,35 +0,0 @@ | |||||||
| <script> |  | ||||||
| import add from "./add.vue"; |  | ||||||
| import list from "./list.vue"; |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "AppClaimAudit", |  | ||||||
|   label: "理赔审核", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     currentPage() { |  | ||||||
|       let {hash} = this.$route |  | ||||||
|       return ["#audit", "#add"].includes(hash) ? add : list |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.dict.load("auditStatus", "insureType", "insureStatus", "category", "variety") |  | ||||||
|   }, |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <section class="AppClaimAudit"> |  | ||||||
|     <component :is="currentPage" v-bind="$props"/> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .AppClaimAudit { |  | ||||||
|   height: 100%; |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,160 +0,0 @@ | |||||||
| <script> |  | ||||||
| import {mapState} from "vuex" |  | ||||||
| import AiEartagPicker from "@project/xumu/components/AiEartagPicker.vue"; |  | ||||||
| import AiSelect from "dui/packages/basic/AiSelect.vue"; |  | ||||||
|  |  | ||||||
| const records = [ |  | ||||||
|   {label: "序号", type: "index"}, |  | ||||||
|   {label: "报案号", prop: "reportNo"}, |  | ||||||
|   {label: "审批状态", prop: "auditStatus", dict: "auditStatus"}, |  | ||||||
|   {label: "审批时间", prop: "auditTime"}, |  | ||||||
|   {label: "审批人", prop: "auditName"}, |  | ||||||
| ] |  | ||||||
| export default { |  | ||||||
|   name: "claimAdd", |  | ||||||
|   components: {AiSelect, AiEartagPicker}, |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     permissions: Function, |  | ||||||
|     dict: Object |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       detail: {detailList: []}, |  | ||||||
|       records |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     ...mapState(["user"]), |  | ||||||
|     userinfo: v => v.user.info || {}, |  | ||||||
|     pageTitle: v => { |  | ||||||
|       const appName = v.$parent.menuName || v.$parent.$options.label |  | ||||||
|       return v.isAudit ? `${appName}审批` : `${appName}详情` |  | ||||||
|     }, |  | ||||||
|     isAudit: v => v.$route.hash == "#audit", |  | ||||||
|     formImages: v => [ |  | ||||||
|       {label: "勘察报告书", prop: "surveyPicture"}, |  | ||||||
|       {label: "无害化回执单", prop: "receiptPicture"}, |  | ||||||
|     ], |  | ||||||
|     columns: v => [ |  | ||||||
|       {label: "序号", type: "index"}, |  | ||||||
|       {label: "生物芯片耳标号", prop: "biochipEarNumber"}, |  | ||||||
|       {label: "身长测量照片", prop: "heightPicture", upload: {instance: v.instance, readonly: !0, valueIsUrl: !0, limit: 1}}, |  | ||||||
|       {label: "电子耳标照片", prop: "earNumberPicture", upload: {instance: v.instance, readonly: !0, valueIsUrl: !0, limit: 1}}, |  | ||||||
|       {label: "防疫耳标照片", prop: "preventionPicture", upload: {instance: v.instance, readonly: !0, valueIsUrl: !0, limit: 1}}, |  | ||||||
|       {label: "无害化处理照片", prop: "harmlessPicture", upload: {instance: v.instance, readonly: !0, valueIsUrl: !0, limit: 1}}, |  | ||||||
|     ].filter(e => !e.hide), |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     back(params = {}) { |  | ||||||
|       this.$router.push(params) |  | ||||||
|     }, |  | ||||||
|     getDetail() { |  | ||||||
|       const {id} = this.$route.query |  | ||||||
|       return id && this.instance.post("/api/insurance/claim/apply/getAuditInfo", null, {params: {id}}).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           const detail = res.data |  | ||||||
|           return this.detail = {...detail} |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     submit() { |  | ||||||
|       this.$refs.detail.validate().then(() => { |  | ||||||
|         this.instance.post("/api/insurance/claim/apply/audit", {...this.detail}).then(res => { |  | ||||||
|           if (res?.code == '0') { |  | ||||||
|             this.$message.success("提交成功!") |  | ||||||
|             this.back() |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }) |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.getDetail() |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <ai-page :title="pageTitle" class="claimAdd" showBack content-string="blank"> |  | ||||||
|     <el-form size="small" label-width="120px" :model="detail" ref="detail"> |  | ||||||
|       <ai-card title="基础信息"> |  | ||||||
|         <div class="grid"> |  | ||||||
|           <el-form-item label="养殖场" prop="farmId"> |  | ||||||
|             <b v-text="detail.farmName"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="承保公司" prop="companyId"> |  | ||||||
|             <b v-text="detail.companyName"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="投保类型"> |  | ||||||
|             <ai-input :value="dict.getLabel('insureType',detail.insureType)" :edit="!1"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="保险产品" prop="productType"> |  | ||||||
|             <b v-text="detail.productType"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="联系人"> |  | ||||||
|             <ai-input v-model="detail.contacts" :edit="!1"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="联系电话"> |  | ||||||
|             <ai-input v-model="detail.phone" :edit="!1"/> |  | ||||||
|           </el-form-item> |  | ||||||
|         </div> |  | ||||||
|       </ai-card> |  | ||||||
|       <ai-card title="投保对象"> |  | ||||||
|         <ai-table :tableData="detail.detailList" :colConfigs="columns" :isShowPagination="!1" hideOptions/> |  | ||||||
|       </ai-card> |  | ||||||
|       <ai-card title="理赔材料"> |  | ||||||
|         <el-form-item v-for="(img,i) in formImages" :key="i" v-bind="img"> |  | ||||||
|           <ai-uploader v-model="detail[img.prop]" value-is-url readonly/> |  | ||||||
|         </el-form-item> |  | ||||||
|       </ai-card> |  | ||||||
|       <ai-card title="审核信息"> |  | ||||||
|         <div class="grid"> |  | ||||||
|           <template v-if="isAudit"> |  | ||||||
|             <el-form-item label="审批状态" prop="auditStatus" :rules="{required:true,message:'请选择审批状态'}"> |  | ||||||
|               <ai-select v-model="detail.auditStatus" dict="auditStatus"/> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="理赔资料" class="sc-3"> |  | ||||||
|               <ai-uploader v-model="detail.picture" value-is-url :instance="instance" :limit="1"/> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="报案号" prop="reportNo" :rules="{required:true,message:'请输入 报案号'}"> |  | ||||||
|               <ai-input v-model="detail.reportNo"/> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="说明"> |  | ||||||
|               <ai-input type="textarea" :rows="3" v-model="detail.remarks"/> |  | ||||||
|             </el-form-item> |  | ||||||
|           </template> |  | ||||||
|           <template v-else> |  | ||||||
|             <el-form-item label="审核状态">{{ dict.getLabel('auditStatus', detail.auditStatus) }}</el-form-item> |  | ||||||
|             <el-form-item label="理赔资料" class="sc-3"> |  | ||||||
|               <el-image :src="detail.picture" :preview-src-list="[detail.picture]"/> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="审核时间">{{ detail.auditTime }}</el-form-item> |  | ||||||
|             <el-form-item label="审核人">{{ detail.auditName }}</el-form-item> |  | ||||||
|             <el-form-item label="说明">{{ detail.remarks }}</el-form-item> |  | ||||||
|           </template> |  | ||||||
|         </div> |  | ||||||
|       </ai-card> |  | ||||||
|     </el-form> |  | ||||||
|     <div slot="footer"> |  | ||||||
|       <template v-if="isAudit"> |  | ||||||
|         <el-button type="primary" @click="submit">提交</el-button> |  | ||||||
|       </template> |  | ||||||
|       <el-button @click="back">返回</el-button> |  | ||||||
|     </div> |  | ||||||
|   </ai-page> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .claimAdd { |  | ||||||
|   :deep(.el-form--label-top) { |  | ||||||
|     .el-form-item__label { |  | ||||||
|       width: 100% !important; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .el-form-item__content { |  | ||||||
|       margin-left: unset !important; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,107 +0,0 @@ | |||||||
| <script> |  | ||||||
| import {mapState} from "vuex" |  | ||||||
|  |  | ||||||
| const columns = [ |  | ||||||
|   {label: "序号", type: "index"}, |  | ||||||
|   {label: "报案号", prop: "reportNo"}, |  | ||||||
|   {label: "投保单号", prop: "orderNo"}, |  | ||||||
|   {label: "所属养殖户", prop: "applyName"}, |  | ||||||
|   {label: "投保类型", prop: "insureType", dict: "insureType"}, |  | ||||||
|   {label: "理赔数量", prop: "claimNumber"}, |  | ||||||
|   {label: "审批状态", prop: "auditStatus", dict: "auditStatus"}, |  | ||||||
|   {label: "审批时间", prop: "auditTime"}, |  | ||||||
|   {label: "审批人", prop: "auditName"}, |  | ||||||
| ] |  | ||||||
| export default { |  | ||||||
|   name: "claimList", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       columns, |  | ||||||
|       tableData: [], |  | ||||||
|       page: {pageNum: 1, pageSize: 10, total: 0}, |  | ||||||
|       search: {}, |  | ||||||
|       dialog: false, |  | ||||||
|       form: {} |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     ...mapState(['user']), |  | ||||||
|     userinfo: v => v.user.info || {}, |  | ||||||
|     pageTitle: v => v.$parent.menuName || v.$parent.$options.label |  | ||||||
|   }, |  | ||||||
|   watch: { |  | ||||||
|     search: { |  | ||||||
|       deep: true, |  | ||||||
|       handler() { |  | ||||||
|         this.page.pageNum = 1 |  | ||||||
|         this.getTableData() |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     getTableData() { |  | ||||||
|       this.instance.post("/api/insurance/claim/apply/getAuditPage", {...this.page, ...this.search}).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           this.tableData = res.data?.records.map(e => ({...e, permit: `${e.status}` + e.auditStatus})) |  | ||||||
|           this.page.total = res.data.total |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.getTableData() |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <ai-page class="claimList" :title="pageTitle"> |  | ||||||
|     <ai-search-bar> |  | ||||||
|       <template #left> |  | ||||||
|         <ai-input placeholder="投保订单号" v-model="search.orderNo"/> |  | ||||||
|         <ai-select placeholder="全部投保类型" v-model="search.insureType" dict="insureType"/> |  | ||||||
|         <ai-select placeholder="全部审批状态" v-model="search.auditStatus" dict="auditStatus"/> |  | ||||||
|         <ai-select placeholder="全部投保状态" v-model="search.status" dict="insureStatus"/> |  | ||||||
|         <ai-search label="投保日期"> |  | ||||||
|           <el-date-picker value-format="yyyy-MM-dd HH:mm:ss" v-model="search.beginDate" type="datetime" placeholder="开始日期" size="small"/> |  | ||||||
|           <el-date-picker value-format="yyyy-MM-dd HH:mm:ss" v-model="search.endDate" type="datetime" placeholder="结束日期" size="small"/> |  | ||||||
|         </ai-search> |  | ||||||
|         <ai-input placeholder="养殖户" v-model="search.applyName"/> |  | ||||||
|         <ai-input placeholder="养殖场" v-model="search.farmName"/> |  | ||||||
|       </template> |  | ||||||
|     </ai-search-bar> |  | ||||||
|     <ai-search-bar> |  | ||||||
|       <template #left> |  | ||||||
|         <ai-download :instance="instance" url="/api/insurance/claim/apply/exportAudit" :params="{...search,...page}" :fileName="`${pageTitle}导出表-${Date.now()}`"/> |  | ||||||
|       </template> |  | ||||||
|     </ai-search-bar> |  | ||||||
|     <ai-table :tableData="tableData" :colConfigs="columns" :dict="dict" @getList="getTableData" |  | ||||||
|               :total="page.total" :current.sync="page.pageNum" :size.sync="page.pageSize"> |  | ||||||
|       <el-table-column slot="options" label="操作" fixed="right" align="center"> |  | ||||||
|         <template slot-scope="{row}"> |  | ||||||
|           <div class="table-options"> |  | ||||||
|             <template v-if="['1'].includes(row.auditStatus)"> |  | ||||||
|               <el-button type="text" @click="$router.push({hash:'#audit',query:{id:row.id}})">审核</el-button> |  | ||||||
|             </template> |  | ||||||
|             <el-button v-else type="text" @click="$router.push({hash:'#add',query:{id:row.id}})">查看</el-button> |  | ||||||
|           </div> |  | ||||||
|         </template> |  | ||||||
|       </el-table-column> |  | ||||||
|     </ai-table> |  | ||||||
|   </ai-page> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .claimList { |  | ||||||
|   height: 100%; |  | ||||||
|  |  | ||||||
|   .deleteBtn { |  | ||||||
|     color: $errorColor; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,35 +0,0 @@ | |||||||
| <script> |  | ||||||
| import add from "./add.vue"; |  | ||||||
| import list from "./list.vue"; |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "AppDeathAudit", |  | ||||||
|   label: "死亡审核", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     currentPage() { |  | ||||||
|       let {hash} = this.$route |  | ||||||
|       return ["#audit", "#add"].includes(hash) ? add : list |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.dict.load("auditStatus", "deathReason", "category", "variety") |  | ||||||
|   }, |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <section class="AppDeathAudit"> |  | ||||||
|     <component :is="currentPage" v-bind="$props"/> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .AppDeathAudit { |  | ||||||
|   height: 100%; |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,153 +0,0 @@ | |||||||
| <script> |  | ||||||
| import {mapState} from "vuex" |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "deathAdd", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     permissions: Function, |  | ||||||
|     dict: Object |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       detail: {detailList: []} |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     ...mapState(["user"]), |  | ||||||
|     userinfo: v => v.user.info || {}, |  | ||||||
|     pageTitle: v => { |  | ||||||
|       const appName = v.$parent.menuName || v.$parent.$options.label |  | ||||||
|       return v.isAudit ? `${appName}审批` : `${appName}详情` |  | ||||||
|     }, |  | ||||||
|     isAudit: v => v.$route.hash == "#audit", |  | ||||||
|     formImages: v => [ |  | ||||||
|       {label: "身长测量照片", prop: "heightPic"}, |  | ||||||
|       {label: "生物芯片照片", prop: "biochipPic"}, |  | ||||||
|       {label: "防疫耳标照片", prop: "preventionPic"}, |  | ||||||
|       {label: "其他说明照片", prop: "otherPic"}, |  | ||||||
|     ], |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     back(params = {}) { |  | ||||||
|       this.$router.push(params) |  | ||||||
|     }, |  | ||||||
|     getDetail() { |  | ||||||
|       const {id} = this.$route.query |  | ||||||
|       return id && this.instance.post("/api/breed/death/page", null, {params: {id}}).then(res => { |  | ||||||
|         if (res?.data?.records) { |  | ||||||
|           const detail = res.data.records[0] || {} |  | ||||||
|           if (detail.picture) { |  | ||||||
|             Object.entries(JSON.parse(detail.picture)).forEach(([key, value]) => { |  | ||||||
|               detail[key] = value |  | ||||||
|             }) |  | ||||||
|           } |  | ||||||
|           return this.detail = {...detail} |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     submit() { |  | ||||||
|       this.$refs.detail.validate().then(() => { |  | ||||||
|         this.instance.post("/api/breed/death/audit", {...this.detail}).then(res => { |  | ||||||
|           if (res?.code == '0') { |  | ||||||
|             this.$message.success("提交成功!") |  | ||||||
|             this.back() |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }) |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.getDetail() |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <ai-page :title="pageTitle" class="deathAdd" showBack content-string="blank"> |  | ||||||
|     <el-form size="small" label-width="120px" :model="detail" ref="detail"> |  | ||||||
|       <ai-card title="基础信息"> |  | ||||||
|         <div class="grid c-4"> |  | ||||||
|           <el-form-item label="生物芯片耳标号" class="row"> |  | ||||||
|             <b v-text="detail.biochipEarNumber"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="养殖场" prop="farmId"> |  | ||||||
|             <b v-text="detail.farmName"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="养殖舍" prop="houseId"> |  | ||||||
|             <b v-text="detail.houseName"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="养殖栏" prop="penId"> |  | ||||||
|             <b v-text="detail.penName"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="电子耳标号" prop="electronicEarNumber"> |  | ||||||
|             <b v-text="detail.electronicEarNumber"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="原厂耳标号" prop="category"> |  | ||||||
|             <b v-text="detail.originalEarNumber"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="类别" prop="category"> |  | ||||||
|             <b v-text="detail.category"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="品种" prop="variety"> |  | ||||||
|             <b v-text="detail.variety"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <div class="row flex"> |  | ||||||
|             <el-form-item v-for="(img,i) in formImages" :key="i" v-bind="img"> |  | ||||||
|               <ai-uploader v-model="detail[img.prop]" value-is-url readonly/> |  | ||||||
|             </el-form-item> |  | ||||||
|           </div> |  | ||||||
|         </div> |  | ||||||
|       </ai-card> |  | ||||||
|       <ai-card title="死亡信息"> |  | ||||||
|         <el-form-item label="死亡原因"> |  | ||||||
|           <b v-text="dict.getLabel('deathReason',detail.reason)"/> |  | ||||||
|         </el-form-item> |  | ||||||
|         <el-form-item label="死亡日期"> |  | ||||||
|           <b v-text="detail.deathTime"/> |  | ||||||
|         </el-form-item> |  | ||||||
|         <el-form-item label="备注"> |  | ||||||
|           <b v-text="detail.remark"/> |  | ||||||
|         </el-form-item> |  | ||||||
|       </ai-card> |  | ||||||
|       <ai-card title="审核信息"> |  | ||||||
|         <div class="grid"> |  | ||||||
|           <template v-if="isAudit"> |  | ||||||
|             <el-form-item label="审批状态" prop="auditStatus" :rules="{required:true,message:'请选择审批状态'}"> |  | ||||||
|               <ai-select v-model="detail.auditStatus" dict="auditStatus"/> |  | ||||||
|             </el-form-item> |  | ||||||
|             <el-form-item label="意见"> |  | ||||||
|               <ai-input type="textarea" :rows="3" v-model="detail.remark"/> |  | ||||||
|             </el-form-item> |  | ||||||
|           </template> |  | ||||||
|           <template v-else> |  | ||||||
|             <el-form-item label="审核状态">{{ dict.getLabel('auditStatus', detail.auditStatus) }}</el-form-item> |  | ||||||
|             <el-form-item label="审核时间">{{ detail.auditTime }}</el-form-item> |  | ||||||
|             <el-form-item label="审核人">{{ detail.auditName }}</el-form-item> |  | ||||||
|             <el-form-item label="意见">{{ detail.remarks }}</el-form-item> |  | ||||||
|           </template> |  | ||||||
|         </div> |  | ||||||
|       </ai-card> |  | ||||||
|     </el-form> |  | ||||||
|     <div slot="footer"> |  | ||||||
|       <template v-if="isAudit"> |  | ||||||
|         <el-button type="primary" @click="submit">提交</el-button> |  | ||||||
|       </template> |  | ||||||
|       <el-button @click="back">返回</el-button> |  | ||||||
|     </div> |  | ||||||
|   </ai-page> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .deathAdd { |  | ||||||
|   :deep(.el-form--label-top) { |  | ||||||
|     .el-form-item__label { |  | ||||||
|       width: 100% !important; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .el-form-item__content { |  | ||||||
|       margin-left: unset !important; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,112 +0,0 @@ | |||||||
| <script> |  | ||||||
| import {mapState} from "vuex" |  | ||||||
|  |  | ||||||
| const columns = [ |  | ||||||
|   {label: "序号", type: "index"}, |  | ||||||
|   {label: "养殖场", format: (v, row) => `${[row.farmName, row.houseName, row.penName].join("-")}`}, |  | ||||||
|   {label: "生物芯片耳标号", prop: "biochipEarNumber"}, |  | ||||||
|   {label: "类别", prop: "category", dict: "category", width: 120}, |  | ||||||
|   {label: "品种", prop: "variety", dict: "variety", width: 120}, |  | ||||||
|   {label: "日龄(天)", prop: "age", width: 80}, |  | ||||||
|   {label: "死亡时间", prop: "deathTime"}, |  | ||||||
|   {label: "死亡原因", prop: "reason", dict: "deathReason", width: 80}, |  | ||||||
|   {label: "登记时间", prop: "createTime"}, |  | ||||||
|   {label: "操作人", prop: "userName", width: 100}, |  | ||||||
|   {label: "审核状态", prop: "auditStatus", dict: "auditStatus", width: 80}, |  | ||||||
| ] |  | ||||||
| export default { |  | ||||||
|   name: "deathList", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       columns, |  | ||||||
|       tableData: [], |  | ||||||
|       page: {pageNum: 1, pageSize: 10, total: 0}, |  | ||||||
|       search: {}, |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     ...mapState(['user']), |  | ||||||
|     userinfo: v => v.user.info || {}, |  | ||||||
|     pageTitle: v => v.$parent.menuName || v.$parent.$options.label |  | ||||||
|   }, |  | ||||||
|   watch: { |  | ||||||
|     search: { |  | ||||||
|       deep: true, |  | ||||||
|       handler() { |  | ||||||
|         this.page.pageNum = 1 |  | ||||||
|         this.getTableData() |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     getTableData() { |  | ||||||
|       this.instance.post("/api/breed/death/getAuditPage", {...this.page, ...this.search}).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           this.tableData = res.data?.records.map(e => ({...e, permit: `${e.status}` + e.auditStatus})) |  | ||||||
|           this.page.total = res.data.total |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.getTableData() |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <ai-page class="deathList" :title="pageTitle"> |  | ||||||
|     <ai-search-bar> |  | ||||||
|       <template #left> |  | ||||||
|         <ai-select placeholder="全部养殖场" v-model="search.farmId" :instance="instance" :action="`/api/siteUser/querySiteByUserId?userId=${userinfo.id}`" :prop="{label:'name'}"/> |  | ||||||
|         <ai-select placeholder="全部养殖舍" v-model="search.houseId" :instance="instance" :action="`/api/siteUser/querySiteById?id=${search.farmId||-1}`" :prop="{label:'name'}"/> |  | ||||||
|         <ai-select placeholder="全部养殖栏" v-model="search.penId" :instance="instance" :action="`/api/siteUser/querySiteById?id=${search.houseId||-1}`" :prop="{label:'name'}"/> |  | ||||||
|         <ai-select placeholder="全部审核状态" v-model="search.auditStatus" dict="auditStatus"/> |  | ||||||
|         <ai-search label="死亡日期"> |  | ||||||
|           <el-date-picker value-format="yyyy-MM-dd HH:mm:ss" v-model="search.deathBeginDate" type="datetime" placeholder="开始日期" size="small"/> |  | ||||||
|           <el-date-picker value-format="yyyy-MM-dd HH:mm:ss" v-model="search.deathEndDate" type="datetime" placeholder="结束日期" size="small"/> |  | ||||||
|         </ai-search> |  | ||||||
|         <ai-search label="登记日期"> |  | ||||||
|           <el-date-picker value-format="yyyy-MM-dd HH:mm:ss" v-model="search.beginDate" type="datetime" placeholder="开始日期" size="small"/> |  | ||||||
|           <el-date-picker value-format="yyyy-MM-dd HH:mm:ss" v-model="search.endDate" type="datetime" placeholder="结束日期" size="small"/> |  | ||||||
|         </ai-search> |  | ||||||
|         <ai-input placeholder="原场耳标号" v-model="search.originalEarNumber"/> |  | ||||||
|         <ai-input placeholder="生物芯片耳标号" v-model="search.biochipEarNumber"/> |  | ||||||
|         <ai-input placeholder="电子耳标号" v-model="search.electronicEarNumber"/> |  | ||||||
|       </template> |  | ||||||
|     </ai-search-bar> |  | ||||||
|     <ai-search-bar> |  | ||||||
|       <template #left> |  | ||||||
|         <ai-download :instance="instance" url="/api/breed/death/export" :params="{...search,...page}" :fileName="`${pageTitle}导出表-${Date.now()}`"/> |  | ||||||
|       </template> |  | ||||||
|     </ai-search-bar> |  | ||||||
|     <ai-table :tableData="tableData" :colConfigs="columns" :dict="dict" @getList="getTableData" |  | ||||||
|               :total="page.total" :current.sync="page.pageNum" :size.sync="page.pageSize"> |  | ||||||
|       <el-table-column slot="options" label="操作" fixed="right" align="center"> |  | ||||||
|         <template slot-scope="{row}"> |  | ||||||
|           <div class="table-options"> |  | ||||||
|             <template v-if="['1'].includes(row.auditStatus)"> |  | ||||||
|               <el-button type="text" @click="$router.push({hash:'#audit',query:{id:row.id}})">审核</el-button> |  | ||||||
|             </template> |  | ||||||
|             <el-button v-else type="text" @click="$router.push({hash:'#add',query:{id:row.id}})">查看</el-button> |  | ||||||
|           </div> |  | ||||||
|         </template> |  | ||||||
|       </el-table-column> |  | ||||||
|     </ai-table> |  | ||||||
|   </ai-page> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .deathList { |  | ||||||
|   height: 100%; |  | ||||||
|  |  | ||||||
|   .deleteBtn { |  | ||||||
|     color: $errorColor; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,35 +0,0 @@ | |||||||
| <script> |  | ||||||
| import add from "./add.vue"; |  | ||||||
| import list from "./list.vue"; |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "AppDeathManage", |  | ||||||
|   label: "死亡登记", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     currentPage() { |  | ||||||
|       let { hash } = this.$route |  | ||||||
|       return hash == "#add" ? add : list |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.dict.load("yesOrNo", "category", "variety", "deathReason", "auditStatus") |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <section class="AppDeathManage"> |  | ||||||
|     <component :is="currentPage" v-bind="$props" /> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .AppDeathManage { |  | ||||||
|   height: 100%; |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,167 +0,0 @@ | |||||||
| <script> |  | ||||||
| import {mapState} from "vuex" |  | ||||||
| import AiEartagRemote from "@project/xumu/components/AiEartagRemote.vue"; |  | ||||||
|  |  | ||||||
| const formImages = [ |  | ||||||
|   {label: "身长测量照片", prop: "heightPic",}, |  | ||||||
|   {label: "生物芯片照片", prop: "biochipPic",}, |  | ||||||
|   {label: "防疫耳标照片", prop: "preventionPic",}, |  | ||||||
|   {label: "其他说明照片", prop: "otherPic",}, |  | ||||||
| ] |  | ||||||
| export default { |  | ||||||
|   name: "deathAdd", |  | ||||||
|   components: {AiEartagRemote}, |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     permissions: Function, |  | ||||||
|     dict: Object |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       formImages, |  | ||||||
|       detail: {}, |  | ||||||
|       form: {} |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     ...mapState(["user"]), |  | ||||||
|     userinfo: v => v.user.info || {}, |  | ||||||
|     isAdd: v => !v.$route.query.id, |  | ||||||
|     isEdit: v => v.$route.query.edit == 1, |  | ||||||
|     isAuthing: v => v.detail.auditStatus == 1, |  | ||||||
|     pageTitle: v => { |  | ||||||
|       const appName = v.$parent.menuName || v.$parent.$options.label |  | ||||||
|       return v.$route.query.id ? v.isEdit ? `编辑${appName}` : `${appName}详情` : `新增${appName}` |  | ||||||
|     }, |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     back(params = {}) { |  | ||||||
|       this.$router.push(params) |  | ||||||
|     }, |  | ||||||
|     getDetail(id) { |  | ||||||
|       return id && this.instance.post("/api/breed/death/page", {biochipEarNumber: id}).then(res => { |  | ||||||
|         if (res?.data?.records) { |  | ||||||
|           const detail = res.data.records[0] || {} |  | ||||||
|           if (detail.picture) { |  | ||||||
|             Object.entries(JSON.parse(detail.picture)).forEach(([key, value]) => { |  | ||||||
|               detail[key] = value |  | ||||||
|             }) |  | ||||||
|           } |  | ||||||
|           return this.detail = {...detail} |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     submit() { |  | ||||||
|       this.$refs.detail.validate().then(() => { |  | ||||||
|         const {biochipEarNumber, id, deathTime, heightPic, biochipPic, preventionPic, otherPic, reason, remarks} = this.detail |  | ||||||
|         this.instance.post("/api/breed/death/addOrEdit", { |  | ||||||
|           biochipEarNumber, id, deathTime, picture: JSON.stringify({heightPic, biochipPic, preventionPic, otherPic}), reason, remarks |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res?.code == 0 && res?.data != 1) { |  | ||||||
|             this.$confirm("是否返回列表页?", "提交成功").then(() => this.back()).catch(() => this.getDetail(biochipEarNumber)) |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     handleAudit() { |  | ||||||
|       this.$refs.form.validate().then(() => { |  | ||||||
|         const {id} = this.detail |  | ||||||
|         this.instance.post("/api/breed/death/audit", null, {params: {id, ...this.form}}).then(res => { |  | ||||||
|           if (res?.code == 0) { |  | ||||||
|             this.$message.success("操作成功") |  | ||||||
|             this.back() |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     handlerAutocomplete(value) { |  | ||||||
|       'biochipEarNumber|farmId|houseId|penId|electronicEarNumber|originalEarNumber|category|variety'.split("|").forEach(prop => this.$set(this.detail, prop, value[prop])) |  | ||||||
|     }, |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.getDetail(this.$route.query.id) |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <ai-page :title="pageTitle" class="deathAdd" showBack content-string="blank"> |  | ||||||
|     <el-form size="small" label-width="120px" :model="detail" ref="detail"> |  | ||||||
|       <ai-card title="基础信息"> |  | ||||||
|         <div class="grid c-4"> |  | ||||||
|           <ai-eartag-remote :instance="instance" @enter="handlerAutocomplete" class="row"/> |  | ||||||
|           <el-form-item label="生物芯片耳标号"> |  | ||||||
|             <b v-text="detail.biochipEarNumber"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="养殖场" prop="farmId"> |  | ||||||
|             <b v-text="detail.farmName"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="养殖舍" prop="houseId"> |  | ||||||
|             <b v-text="detail.houseName"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="养殖栏" prop="penId"> |  | ||||||
|             <b v-text="detail.penName"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="电子耳标号" prop="electronicEarNumber"> |  | ||||||
|             <b v-text="detail.electronicEarNumber"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="原厂耳标号" prop="originalEarNumber"> |  | ||||||
|             <b v-text="detail.originalEarNumber"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="类别" prop="category"> |  | ||||||
|             <b v-text="detail.category"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="品种" prop="variety"> |  | ||||||
|             <b v-text="detail.variety"/> |  | ||||||
|           </el-form-item> |  | ||||||
|         </div> |  | ||||||
|       </ai-card> |  | ||||||
|       <ai-card title="上传照片"> |  | ||||||
|         <div class="grid c-4"> |  | ||||||
|           <el-form-item v-for="(img,i) in formImages" :key="i" v-bind="img"> |  | ||||||
|             <ai-uploader v-if="isAdd||isEdit" v-model="detail[img.prop]" :instance="instance" :limit="1" value-is-url/> |  | ||||||
|             <el-image :src="detail[img.prop]" :preview-src-list="[detail[img.prop]]" v-else/> |  | ||||||
|           </el-form-item> |  | ||||||
|         </div> |  | ||||||
|       </ai-card> |  | ||||||
|       <ai-card title="死亡录入"> |  | ||||||
|         <div class="grid"> |  | ||||||
|           <el-form-item label="死亡日期" prop="deathTime" :rules="[{required:isAdd||isEdit,message:'请选择死亡日期'}]"> |  | ||||||
|             <el-date-picker value-format="yyyy-MM-dd HH:mm:ss" v-if="isAdd||isEdit" v-model="detail.deathTime"/> |  | ||||||
|             <b v-else v-text="detail.deathTime"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="死亡原因" prop="reason" :rules="[{required:isAdd||isEdit,message:'请选择死亡原因'}]"> |  | ||||||
|             <ai-select v-if="isAdd||isEdit" v-model="detail.reason" dict="deathReason"/> |  | ||||||
|             <b v-else v-text="dict.getLabel('deathReason',detail.reason)"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="备注" prop="remark" class="row"> |  | ||||||
|             <ai-input type="textarea" :row="3" v-model="detail.remark" :edit="isAdd||isEdit"/> |  | ||||||
|           </el-form-item> |  | ||||||
|         </div> |  | ||||||
|       </ai-card> |  | ||||||
|       <ai-card title="审批信息" v-if="isAuthing"> |  | ||||||
|         <el-form :model="form" size="small" ref="form" label-width="120px"> |  | ||||||
|           <el-form-item label="是否同意" prop="auditStatus" :rules="[{required:true,message:'请选择是否同意'}]"> |  | ||||||
|             <ai-select v-model="form.auditStatus" :select-list="[{dictValue: 2, dictName: '同意'}, {dictValue: 3, dictName: '不同意'}]"/> |  | ||||||
|           </el-form-item> |  | ||||||
|           <el-form-item label="审批意见" prop="auditReason"> |  | ||||||
|             <el-input type="textarea" :row="3" v-model="form.auditReason" clearable placeholder="请输入"/> |  | ||||||
|           </el-form-item> |  | ||||||
|         </el-form> |  | ||||||
|       </ai-card> |  | ||||||
|     </el-form> |  | ||||||
|     <div slot="footer"> |  | ||||||
|       <el-button type="primary" @click="submit" v-if="isAdd||isEdit">提交</el-button> |  | ||||||
|       <el-button type="primary" @click="handleAudit" v-if="isAuthing">提交</el-button> |  | ||||||
|       <el-button @click="back">返回</el-button> |  | ||||||
|     </div> |  | ||||||
|   </ai-page> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .deathAdd { |  | ||||||
|   .el-date-editor { |  | ||||||
|     width: 100%; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,142 +0,0 @@ | |||||||
| <script> |  | ||||||
| import {mapState} from "vuex" |  | ||||||
|  |  | ||||||
| const columns = [ |  | ||||||
|   {label: "序号", type: "index"}, |  | ||||||
|   {label: "养殖场",format: (v, row) => `${[row.farmName, row.houseName, row.penName].join("-")}`}, |  | ||||||
|   {label: "生物芯片耳标号", prop: "biochipEarNumber"}, |  | ||||||
|   {label: "类别", prop: "category", dict: "category", width: 120}, |  | ||||||
|   {label: "品种", prop: "variety", dict: "variety", width: 120}, |  | ||||||
|   {label: "日龄(天)", prop: "age", width: 80}, |  | ||||||
|   {label: "死亡时间", prop: "deathTime"}, |  | ||||||
|   {label: "死亡原因", prop: "reason", dict: "deathReason", width: 80}, |  | ||||||
|   {label: "登记时间", prop: "createTime"}, |  | ||||||
|   {label: "操作人", prop: "userName", width: 100}, |  | ||||||
|   {label: "审核状态", prop: "auditStatus", dict: "auditStatus", width: 80}, |  | ||||||
| ] |  | ||||||
| export default { |  | ||||||
|   name: "deathList", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function |  | ||||||
|   }, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       columns, |  | ||||||
|       tableData: [], |  | ||||||
|       page: {pageNum: 1, pageSize: 10, total: 0}, |  | ||||||
|       search: {}, |  | ||||||
|       dialog: false, |  | ||||||
|       form: {} |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     ...mapState(['user']), |  | ||||||
|     userinfo: v => v.user.info || {}, |  | ||||||
|     pageTitle: v => v.$parent.menuName || v.$parent.$options.label |  | ||||||
|   }, |  | ||||||
|   watch: { |  | ||||||
|     search: { |  | ||||||
|       deep: true, |  | ||||||
|       handler() { |  | ||||||
|         this.page.pageNum = 1 |  | ||||||
|         this.getTableData() |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     getTableData() { |  | ||||||
|       this.instance.post("/api/breed/death/page", {...this.page, ...this.search}).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           this.tableData = res.data?.records |  | ||||||
|           this.page.total = res.data.total |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     handleDelete(id) { |  | ||||||
|       this.$confirm("确定删除该条数据?").then(() => { |  | ||||||
|         this.instance.post("/api/breed/weight/del", null, { |  | ||||||
|           params: {id} |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res?.code == 0) { |  | ||||||
|             this.getTableData() |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     handleAuditAgain(id) { |  | ||||||
|       this.$confirm("是否要再次提交审批?").then(() => { |  | ||||||
|         this.instance.post("/api/breed/death/audit", null, { |  | ||||||
|           params: {id, auditStatus: 1} |  | ||||||
|         }).then(res => { |  | ||||||
|           if (res?.code == '0') { |  | ||||||
|             this.$message.success("提交成功") |  | ||||||
|             this.getTableData() |  | ||||||
|           } |  | ||||||
|         }) |  | ||||||
|       }) |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.getTableData() |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|   <ai-page class="deathList" :title="pageTitle"> |  | ||||||
|     <ai-search-bar> |  | ||||||
|       <template #left> |  | ||||||
|         <ai-select placeholder="全部养殖场" v-model="search.farmId" :instance="instance" :action="`/api/siteUser/querySiteByUserId?userId=${userinfo.id}`" :prop="{label:'name'}"/> |  | ||||||
|         <ai-select placeholder="全部养殖舍" v-model="search.houseId" :instance="instance" :action="`/api/siteUser/querySiteById?id=${search.farmId||-1}`" :prop="{label:'name'}"/> |  | ||||||
|         <ai-select placeholder="全部养殖栏" v-model="search.penId" :instance="instance" :action="`/api/siteUser/querySiteById?id=${search.houseId||-1}`" :prop="{label:'name'}"/> |  | ||||||
|         <ai-select placeholder="全部审核状态" v-model="search.auditStatus" dict="auditStatus"/> |  | ||||||
|         <ai-search label="死亡日期"> |  | ||||||
|           <el-date-picker value-format="yyyy-MM-dd HH:mm:ss" v-model="search.deathBeginDate" type="datetime" placeholder="开始日期" size="small"/> |  | ||||||
|           <el-date-picker value-format="yyyy-MM-dd HH:mm:ss" v-model="search.deathEndDate" type="datetime" placeholder="结束日期" size="small"/> |  | ||||||
|         </ai-search> |  | ||||||
|         <ai-search label="登记日期"> |  | ||||||
|           <el-date-picker value-format="yyyy-MM-dd HH:mm:ss" v-model="search.beginDate" type="datetime" placeholder="开始日期" size="small"/> |  | ||||||
|           <el-date-picker value-format="yyyy-MM-dd HH:mm:ss" v-model="search.endDate" type="datetime" placeholder="结束日期" size="small"/> |  | ||||||
|         </ai-search> |  | ||||||
|         <ai-input placeholder="原场耳标号" v-model="search.originalEarNumber"/> |  | ||||||
|         <ai-input placeholder="生物芯片耳标号" v-model="search.biochipEarNumber"/> |  | ||||||
|         <ai-input placeholder="电子耳标号" v-model="search.electronicEarNumber"/> |  | ||||||
|       </template> |  | ||||||
|     </ai-search-bar> |  | ||||||
|     <ai-search-bar> |  | ||||||
|       <template #left> |  | ||||||
|         <el-button type="primary" icon="iconfont iconAdd" @click="$router.push({hash:'#add'})">新增</el-button> |  | ||||||
|         <ai-download :instance="instance" url="/api/breed/death/export" :params="{...search,...page}" :fileName="`死亡导出表-${Date.now()}`"/> |  | ||||||
|       </template> |  | ||||||
|     </ai-search-bar> |  | ||||||
|     <ai-table :tableData="tableData" :colConfigs="columns" :dict="dict" @getList="getTableData" |  | ||||||
|               :total="page.total" :current.sync="page.pageNum" :size.sync="page.pageSize"> |  | ||||||
|       <el-table-column slot="options" label="操作" fixed="right" align="center"> |  | ||||||
|         <template slot-scope="{row}"> |  | ||||||
|           <div class="table-options"> |  | ||||||
|  |  | ||||||
|             <el-button v-if="row.auditStatus==1" type="text" @click="$router.push({hash:'#add',query:{id:row.biochipEarNumber}})">查看</el-button> |  | ||||||
|             <template v-else> |  | ||||||
|               <el-button v-if="row.auditStatus==2" type="text" @click="$router.push({hash:'#add',query:{id:row.biochipEarNumber}})">查看</el-button> |  | ||||||
|               <el-button v-if="row.auditStatus==2" type="text" @click="$router.push({hash:'#add',query:{id:row.biochipEarNumber,edit:1}})">编辑</el-button> |  | ||||||
|               <el-button v-if="row.auditStatus==3" type="text" @click="handleAuditAgain(row.id)">再次提交</el-button> |  | ||||||
|               <el-button type="text" @click="handleDelete(row.id)">删除</el-button> |  | ||||||
|             </template> |  | ||||||
|           </div> |  | ||||||
|         </template> |  | ||||||
|       </el-table-column> |  | ||||||
|     </ai-table> |  | ||||||
|   </ai-page> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <style scoped lang="scss"> |  | ||||||
| .deathList { |  | ||||||
|   height: 100%; |  | ||||||
|  |  | ||||||
|   .deleteBtn { |  | ||||||
|     color: $errorColor; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,32 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <section class="AppDictionary"> |  | ||||||
|     <component :is="currentPage" v-bind="$props"/> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| import DictDetail from "./dictDetail"; |  | ||||||
| import DictList from "@project/xumu/AppDictionary/dictList.vue"; |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "AppDictionary", |  | ||||||
|   label: "数据字典", |  | ||||||
|   props: { |  | ||||||
|     instance: Function, |  | ||||||
|     dict: Object, |  | ||||||
|     permissions: Function |  | ||||||
|   }, |  | ||||||
|   computed: { |  | ||||||
|     currentPage() { |  | ||||||
|       let {hash} = this.$route |  | ||||||
|       return hash == "#add" ? DictDetail : DictList |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
| .AppDictionary { |  | ||||||
|   height: 100%; |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user