2508 Commits

Author SHA1 Message Date
aixianling
a5dbdbe778 Merge branch 'dev' into vite
# Conflicts:
#	examples/router/autoRoutes.js
#	package.json
#	packages/bigscreen/designer/components/Add.vue
#	project/dv/apps/AppGridDV.vue
#	vue.config.js
2022-08-23 11:14:38 +08:00
aixianling
de190a9076 减少冗余代码 2022-08-23 10:58:14 +08:00
aixianling
efdb76ff0c 异常修复 2022-08-23 10:53:03 +08:00
aixianling
a0d348748c 重新构建一遍okr-tree 2022-08-23 10:41:16 +08:00
aixianling
3c499a1f8d Merge remote-tracking branch 'origin/dev' into dev 2022-08-23 10:39:04 +08:00
aixianling
df498efd2f 重新构建一遍okr-tree 2022-08-23 10:38:33 +08:00
liuye
6561f31e2d css 2022-08-23 08:58:46 +08:00
aixianling
f0edad2b97 okrtree改成cdn加载 2022-08-22 18:04:00 +08:00
aixianling
37e37540f8 okrtree改成cdn加载 2022-08-22 18:03:06 +08:00
shijingjing
8312807917 30953 2022-08-22 17:51:57 +08:00
yanran200730
b52c178051 bug 2022-08-22 17:06:11 +08:00
yanran200730
8c0f9451b7 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-22 16:00:16 +08:00
yanran200730
0a262cbb25 郫都大屏 2022-08-22 16:00:09 +08:00
aixianling
e7fb16bd70 修复状态显示异常 2022-08-22 15:24:36 +08:00
liuye
41810a8b80 宣发统计 2022-08-22 15:03:55 +08:00
liuye
53ee346ba0 上架宣发 2022-08-22 11:42:30 +08:00
liuye
fbfa584d55 30710 2022-08-22 11:30:27 +08:00
liuye
2d834a57d5 宣发统计 2022-08-22 10:44:41 +08:00
aixianling
a8041026a9 临时处理一下 2022-08-19 13:55:13 +08:00
aixianling
e6c3c1c857 BUG 30939 2022-08-19 11:12:07 +08:00
aixianling
37df0942ff BUG 30868 2022-08-19 11:03:44 +08:00
aixianling
3f51798bc1 Merge remote-tracking branch 'origin/dev' into dev 2022-08-19 10:32:25 +08:00
aixianling
85e34eda3d 增加信息标注 2022-08-19 10:32:12 +08:00
liuye
329f7562db 回调 2022-08-19 10:24:51 +08:00
yanran200730
a80efb09c0 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-19 09:42:59 +08:00
yanran200730
122d12fec0 bug 2022-08-19 09:42:46 +08:00
liuye
17bc8ad651 30941 2022-08-19 09:15:46 +08:00
liuye
587028883a fix 2022-08-19 09:01:42 +08:00
liuye
79bfd71a8e fix 2022-08-19 09:00:10 +08:00
yanran200730
8aae3b84a5 bug 2022-08-18 18:33:01 +08:00
yanran200730
238a6807ac Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-18 18:25:09 +08:00
yanran200730
49bd61c376 bug 2022-08-18 18:24:59 +08:00
aixianling
5dac5a8829 Merge remote-tracking branch 'origin/dev' into dev 2022-08-18 17:28:04 +08:00
aixianling
35e612d35c 特制化,使标题跟随菜单目录变化 2022-08-18 17:27:50 +08:00
yanran200730
21fcd206db Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-18 17:14:18 +08:00
yanran200730
dd81c894e0 协同宣发 2022-08-18 17:14:11 +08:00
aixianling
3b7ee0c6cc 固定版本 2022-08-18 16:13:37 +08:00
aixianling
bdc0f0861f BUG 30925 2022-08-18 16:10:11 +08:00
aixianling
a694d33a9c Merge remote-tracking branch 'origin/dev' into dev 2022-08-18 15:36:42 +08:00
aixianling
a92123566d 秀山需求变更调整完毕 2022-08-18 15:36:24 +08:00
shijingjing
8fbdee3a22 分页和日期 2022-08-18 13:49:16 +08:00
shijingjing
583b210687 去掉echerts背景色 2022-08-18 12:21:45 +08:00
shijingjing
378c634c4a sortable: "custom" 2022-08-18 11:45:46 +08:00
shijingjing
3f9deb61f0 30907 2022-08-18 09:53:15 +08:00
yanran200730
154506ec6e 协同宣发 2022-08-18 09:40:09 +08:00
shijingjing
320f9b9948 漏了 2022-08-18 09:32:58 +08:00
aixianling
8b1669ccfc Merge remote-tracking branch 'origin/dev' into dev 2022-08-18 09:24:01 +08:00
aixianling
5eaada7828 BUG 30916 2022-08-18 09:23:44 +08:00
shijingjing
6c3686232c 正负号格式化 2022-08-18 09:12:35 +08:00
shijingjing
34672ebfda 正负号 2022-08-18 09:02:34 +08:00
shijingjing
371ec0c8dd bug 2022-08-17 20:22:25 +08:00
shijingjing
7e974c8de3 事件类型 2022-08-17 20:08:27 +08:00
shijingjing
c153846191 网格 2022-08-17 19:52:30 +08:00
shijingjing
13a56c373c 积分规则 2022-08-17 19:15:57 +08:00
shijingjing
91c4e94609 bug 2022-08-17 19:02:52 +08:00
shijingjing
78d6d9d52d 30916 2022-08-17 18:46:03 +08:00
shijingjing
0df75a6dfa 30915 2022-08-17 18:13:00 +08:00
aixianling
18d00de5fc 增加测试节点 2022-08-17 18:12:35 +08:00
aixianling
1ff28c6969 Merge remote-tracking branch 'origin/dev' into dev 2022-08-17 17:40:57 +08:00
aixianling
f49e5cd8a7 BUG 30910 2022-08-17 17:40:41 +08:00
shijingjing
8a0a805af1 30908 2022-08-17 17:34:21 +08:00
shijingjing
a3da9bacb0 30909 2022-08-17 17:30:10 +08:00
shijingjing
c0de94aca9 30848 2022-08-17 17:21:26 +08:00
aixianling
7500bf286e BUG 30889 2022-08-17 14:48:56 +08:00
aixianling
e3937d2ed6 企微定制方案新增埋点 2022-08-17 13:52:27 +08:00
aixianling
f3b799c56f 企微定制方案新增埋点 2022-08-17 11:52:38 +08:00
aixianling
0e250bbaba BUG 30886 2022-08-17 11:38:23 +08:00
aixianling
69b9001a99 网格选择调整完毕 2022-08-17 11:25:50 +08:00
aixianling
0682de1644 Merge remote-tracking branch 'origin/dev' into dev 2022-08-17 10:51:09 +08:00
aixianling
70e455b88d 修复异常 2022-08-17 10:50:56 +08:00
shijingjing
9a575cff69 log 2022-08-17 09:28:57 +08:00
aixianling
d14371d7dc Merge remote-tracking branch 'origin/dev' into dev 2022-08-17 08:44:17 +08:00
aixianling
b0bd16a53b BUG 30873 2022-08-17 08:43:47 +08:00
shijingjing
00796025a6 30875 2022-08-16 18:28:57 +08:00
shijingjing
59804f5891 30802 2022-08-16 17:36:44 +08:00
shijingjing
ac6d877af9 30836 2022-08-16 16:54:54 +08:00
shijingjing
e3824895b8 漏了 2022-08-16 16:18:18 +08:00
shijingjing
ffe6dc3c8f 默认展开选中节点 2022-08-16 16:17:55 +08:00
shijingjing
492af31f57 网格树 2022-08-16 16:03:08 +08:00
shijingjing
302391894b 30843 2022-08-16 15:06:00 +08:00
shijingjing
16c4b2dfa7 table 2022-08-16 11:36:29 +08:00
shijingjing
baed2d91b7 30839 2022-08-16 11:00:43 +08:00
shijingjing
f7964ebe60 30832 30821 2022-08-16 10:49:10 +08:00
shijingjing
960f5c4940 30830 2022-08-16 09:44:32 +08:00
shijingjing
c4214725be 30826 2022-08-16 09:43:21 +08:00
shijingjing
0ee41d9046 30828 2022-08-16 09:40:23 +08:00
shijingjing
dc9e2278cc 网格回显 2022-08-15 20:22:02 +08:00
shijingjing
c3f7b017f5 校验 2022-08-15 18:59:40 +08:00
shijingjing
e2cae6f692 输入正数最多保留两位小数 2022-08-15 18:56:57 +08:00
shijingjing
e9f63c464f 30825 2022-08-15 18:11:14 +08:00
shijingjing
ba2d83dd43 userName换name 2022-08-15 17:19:12 +08:00
shijingjing
609eb457d8 30823 2022-08-15 17:12:45 +08:00
shijingjing
9e85d12824 积分类型 2022-08-15 16:42:57 +08:00
shijingjing
037547a1d4 30810 2022-08-15 16:38:08 +08:00
shijingjing
f641de929f 余额变动 2022-08-15 15:57:11 +08:00
shijingjing
322cd677b2 30818 2022-08-15 15:19:18 +08:00
shijingjing
83722c8b7d 30817 2022-08-15 15:06:42 +08:00
shijingjing
deed632085 30815 2022-08-15 15:02:55 +08:00
shijingjing
ef00fa435c 30814 2022-08-15 14:56:57 +08:00
shijingjing
1e5b01a446 121183 2022-08-15 14:46:11 +08:00
shijingjing
ad3e7b5f7e 表格排序 2022-08-15 14:41:16 +08:00
shijingjing
3fb0b4bec0 30805 2022-08-15 14:03:18 +08:00
aixianling
ebcb37cdf6 Merge remote-tracking branch 'origin/dev' into dev 2022-08-15 13:52:48 +08:00
aixianling
82063280f7 监测对象增加导出名单 2022-08-15 13:52:34 +08:00
shijingjing
eddd56a0de 文件名称 2022-08-15 13:52:24 +08:00
yanran200730
fc7f522524 郫都大屏 2022-08-15 11:30:32 +08:00
shijingjing
418cc69634 网格员积分 2022-08-15 11:24:25 +08:00
shijingjing
40a73c2a34 echarts label字段超出显示省略号 2022-08-15 08:42:49 +08:00
shijingjing
040cef5028 默认值 2022-08-12 19:01:09 +08:00
shijingjing
a275e873fa 规则 2022-08-12 18:35:02 +08:00
shijingjing
9961da1d25 bug 2022-08-12 16:15:34 +08:00
shijingjing
7032ea6e4f bug 2022-08-12 16:13:25 +08:00
yanran200730
ab2207b109 郫都大屏 2022-08-12 16:11:03 +08:00
yanran200730
1f1dc5eec8 bug 2022-08-12 14:07:46 +08:00
shijingjing
b0b3193457 事件汇总 2022-08-12 11:50:37 +08:00
yanran200730
ffc5682a36 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-12 09:47:41 +08:00
yanran200730
347bd16bb1 bug 2022-08-12 09:47:34 +08:00
aixianling
c3f6fbbffe Merge remote-tracking branch 'origin/dev' into dev 2022-08-12 09:29:56 +08:00
aixianling
d5b104fefd 增加es6兼容 2022-08-12 09:29:37 +08:00
shijingjing
b879c1b0c4 导出 2022-08-11 17:27:21 +08:00
shijingjing
23c5d65e0f 滚动条 2022-08-11 16:49:51 +08:00
yanran200730
bad3028a83 郫都大屏 2022-08-11 16:36:36 +08:00
yanran200730
86dbba831f Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-11 16:14:34 +08:00
yanran200730
52d60210c7 郫都大屏 2022-08-11 16:14:28 +08:00
shijingjing
15eb67168f 统计 2022-08-11 15:11:05 +08:00
aixianling
c08514c60f 增加工作流全局埋点 2022-08-11 15:01:52 +08:00
aixianling
1711b37750 Merge remote-tracking branch 'origin/dev' into dev 2022-08-11 14:25:01 +08:00
aixianling
d5c1bfe913 工作流台账对接完成 2022-08-11 14:24:49 +08:00
shijingjing
c4bee85e6f 统计 2022-08-11 11:41:58 +08:00
aixianling
509379e704 增加权限码控制 2022-08-11 11:14:27 +08:00
aixianling
84aa2f5f62 Merge remote-tracking branch 'origin/dev' into dev 2022-08-11 10:45:35 +08:00
aixianling
277029ad85 上架直接使用标准版居民档案 2022-08-11 10:45:21 +08:00
yanran200730
6861f7f754 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-11 10:31:48 +08:00
yanran200730
5132d41b14 郫都大屏 2022-08-11 10:31:35 +08:00
aixianling
53f9434f53 Merge remote-tracking branch 'origin/dev' into dev 2022-08-11 10:30:51 +08:00
aixianling
cb57ac7b48 整合代码 2022-08-11 10:30:31 +08:00
shijingjing
e404cc1417 积分 2022-08-11 09:54:52 +08:00
yanran200730
bcec48bdbf Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-11 09:28:51 +08:00
yanran200730
188d0ed258 郫都大屏 2022-08-11 09:28:44 +08:00
liuye
a9a466cca5 选择部门 2022-08-11 09:15:22 +08:00
yanran200730
ff8120d1b5 30786 2022-08-11 08:21:56 +08:00
yanran200730
e4707cb090 30798 2022-08-11 08:14:04 +08:00
shijingjing
3d13fd5d54 积分明细 2022-08-10 18:53:38 +08:00
aixianling
54c79d94fb Merge remote-tracking branch 'origin/dev' into dev 2022-08-10 18:06:22 +08:00
aixianling
bcabbb8a6a 新增流程组件 2022-08-10 18:06:09 +08:00
yanran200730
98f732a7cf Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-10 18:01:26 +08:00
yanran200730
9c47fb9a16 郫都大屏 2022-08-10 18:01:19 +08:00
aixianling
5ba4df87fb 展示流程ID 2022-08-10 17:44:06 +08:00
aixianling
6b173f2c29 Merge remote-tracking branch 'origin/dev' into dev 2022-08-10 17:41:56 +08:00
aixianling
55da7871ee 流程台账界面完成 2022-08-10 17:41:42 +08:00
yanran200730
bd67f05f91 郫都大屏 2022-08-10 17:26:44 +08:00
yanran200730
f871cefbad 郫都大屏 2022-08-10 17:25:31 +08:00
yanran200730
83b7bdef8d 郫都大屏 2022-08-10 17:19:01 +08:00
yanran200730
46124ecf9c Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-10 17:03:25 +08:00
yanran200730
97181c4e8d 30796 2022-08-10 17:03:18 +08:00
aixianling
bf1348fa63 Merge remote-tracking branch 'origin/dev' into dev 2022-08-10 16:59:09 +08:00
aixianling
c5b2b233b2 工作流配置完成 2022-08-10 16:58:52 +08:00
yanran200730
36e189f569 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-10 16:49:39 +08:00
yanran200730
43976b674a bug 2022-08-10 16:49:32 +08:00
shijingjing
c9c552bd4a 积分管理 2022-08-10 16:47:22 +08:00
yanran200730
7b0a7bf741 郫都大屏 2022-08-10 15:19:57 +08:00
yanran200730
1c41f96f04 郫都大屏 2022-08-10 14:54:19 +08:00
yanran200730
bd228bcd91 郫都大屏 2022-08-10 14:49:21 +08:00
yanran200730
fbb9271966 郫都大屏 2022-08-10 11:37:02 +08:00
yanran200730
6598c138c0 郫都大屏 2022-08-10 11:28:34 +08:00
yanran200730
01a9997c86 郫都大屏 2022-08-10 11:27:25 +08:00
yanran200730
605599efc4 大屏 2022-08-10 11:15:13 +08:00
yanran200730
25ca7f4027 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-10 11:14:05 +08:00
yanran200730
f28e915c4a 大屏 2022-08-10 11:14:00 +08:00
aixianling
3d386d76e4 BUG 30793 2022-08-10 11:10:36 +08:00
aixianling
b001ef0bd5 Merge remote-tracking branch 'origin/dev' into dev 2022-08-10 11:07:05 +08:00
aixianling
73a26d8560 优化字典类 2022-08-10 11:06:49 +08:00
yanran200730
fa37a9cfc0 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-10 10:59:19 +08:00
yanran200730
b33faf19f7 大屏 2022-08-10 10:59:13 +08:00
aixianling
09d96a3c95 Merge remote-tracking branch 'origin/dev' into dev 2022-08-10 10:18:55 +08:00
aixianling
eb2d76de61 BUG 30794 2022-08-10 10:18:35 +08:00
yanran200730
4f6d6b9e77 bug 2022-08-10 09:55:22 +08:00
shijingjing
c0302ce05c 数组转树形结构 2022-08-10 09:47:45 +08:00
liuye
c06d38bb5f 宣发效果时间格式 2022-08-10 09:29:47 +08:00
aixianling
9bd1f380be Merge remote-tracking branch 'origin/dev' into dev 2022-08-09 17:56:18 +08:00
aixianling
caeaccef37 BUG 30792 2022-08-09 17:55:59 +08:00
yanran200730
9bd9a1375c Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-09 17:52:39 +08:00
yanran200730
e2c7e81482 30791 2022-08-09 17:52:30 +08:00
shijingjing
c6f3552c56 no message 2022-08-09 17:39:20 +08:00
shijingjing
215e13d19d 统计 2022-08-09 17:07:09 +08:00
yanran200730
5aead81caa 30782 2022-08-09 16:26:59 +08:00
yanran200730
37b470cc6c 30779 2022-08-09 14:49:42 +08:00
yanran200730
01fd644312 30783 2022-08-09 14:40:52 +08:00
yanran200730
cb3f7da491 30784 2022-08-09 14:36:08 +08:00
yanran200730
1ce37c38af 30780 2022-08-09 14:29:10 +08:00
yanran200730
f8dbd96dc2 30778 2022-08-09 14:25:55 +08:00
yanran200730
61716196cd 30778 2022-08-09 14:24:39 +08:00
yanran200730
9bf8f4f754 30782 2022-08-09 14:19:57 +08:00
yanran200730
8229258af4 30785 2022-08-09 14:17:17 +08:00
yanran200730
a12a2b2d72 30781 2022-08-09 14:03:58 +08:00
yanran200730
dc1075f865 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-09 11:20:07 +08:00
yanran200730
fe14f74288 bug 2022-08-09 11:20:00 +08:00
shijingjing
75f2349e76 统计 2022-08-09 10:19:22 +08:00
yanran200730
c6a515554f bug 2022-08-09 09:37:22 +08:00
yanran200730
4aa1d4259d 30769 2022-08-09 09:26:20 +08:00
yanran200730
5d9ea10cb0 优化 2022-08-09 09:01:41 +08:00
yanran200730
d1b6b69807 30770 2022-08-08 17:57:41 +08:00
yanran200730
068af5e40e 30762 2022-08-08 17:48:34 +08:00
yanran200730
067410f636 30771 2022-08-08 17:44:49 +08:00
aixianling
8a7867d6ea Merge remote-tracking branch 'origin/dev' into dev 2022-08-08 17:39:52 +08:00
aixianling
ab531d3b08 scss全局变量预加载处理 2022-08-08 17:39:39 +08:00
shijingjing
11ce529591 网格员详情 2022-08-08 17:39:01 +08:00
yanran200730
bc1a226039 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-08 17:24:16 +08:00
yanran200730
8934545c00 30765 2022-08-08 17:24:08 +08:00
shijingjing
a8056ae1ca css调整 2022-08-08 16:00:12 +08:00
aixianling
c4ca30768b Merge remote-tracking branch 'origin/dev' into dev 2022-08-08 15:39:33 +08:00
aixianling
1f4081e2bb 迁移saas版首页应用进入产品库 2022-08-08 15:39:13 +08:00
shijingjing
8d4d986332 名字写错了 2022-08-08 15:34:44 +08:00
liuye
55cbd9c60c 30774 2022-08-08 14:51:34 +08:00
shijingjing
697b561cac 结构调整 2022-08-08 14:09:47 +08:00
aixianling
868149e480 Merge remote-tracking branch 'origin/dev' into dev 2022-08-08 14:08:28 +08:00
aixianling
488e2298de 企微构建新增指定默认首页 2022-08-08 14:07:53 +08:00
yanran200730
5c60f1ffb7 bug 2022-08-08 11:54:09 +08:00
yanran200730
b957c92533 优化 2022-08-08 11:31:16 +08:00
yanran200730
941b7c80d4 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-08 11:24:29 +08:00
yanran200730
2ee8676c4e 优化 2022-08-08 11:24:21 +08:00
shijingjing
6b0852bbbc css调整 2022-08-08 11:06:43 +08:00
aixianling
8eda688d37 企微控制是否为单服务 2022-08-08 11:06:32 +08:00
shijingjing
6d90c17ed3 网格员积分 2022-08-08 09:32:36 +08:00
shijingjing
3b467c3e51 积分详情 2022-08-05 16:57:02 +08:00
shijingjing
567bde994f 积分统计 2022-08-05 14:30:31 +08:00
shijingjing
efd7d00fa9 新闻详情 2022-08-05 10:03:08 +08:00
shijingjing
8d245eea07 版本回退 2022-08-05 09:16:52 +08:00
shijingjing
8e9db3ddf8 详情 2022-08-04 18:03:12 +08:00
yanran200730
1dacec1de0 bug 2022-08-04 17:57:45 +08:00
aixianling
f005576cb6 Merge remote-tracking branch 'origin/dev' into dev 2022-08-04 16:36:21 +08:00
aixianling
a01f1cb547 BUG 30759 2022-08-04 16:36:02 +08:00
shijingjing
c9e74b7a8c aititle插槽 2022-08-04 16:16:39 +08:00
shijingjing
3e03d087b2 详情弹窗 2022-08-04 16:08:34 +08:00
shijingjing
3452420e52 积分统计 2022-08-04 15:05:54 +08:00
shijingjing
f321fc8986 积分统计 2022-08-04 14:40:43 +08:00
shijingjing
59a4be64b5 网格员积分详情 2022-08-04 11:34:43 +08:00
aixianling
22b51bf673 Merge remote-tracking branch 'origin/dev' into dev 2022-08-04 09:09:10 +08:00
aixianling
31d641fdab 政策申办=>贷款联审 傻逼设计 2022-08-04 09:08:46 +08:00
shijingjing
81b309fa1c 积分 2022-08-03 15:57:55 +08:00
shijingjing
9816eca8a2 积分规则 2022-08-03 14:16:25 +08:00
shijingjing
f75885415c 网格员积分 2022-08-03 11:11:42 +08:00
yanran200730
2e90b6adf0 大屏 2022-08-02 17:47:11 +08:00
yanran200730
845db90a35 bug 2022-08-02 16:03:29 +08:00
yanran200730
192277c870 bug 2022-08-02 15:37:10 +08:00
yanran200730
53e318a27c Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-02 14:48:45 +08:00
yanran200730
4189b41a2f 30720 2022-08-02 14:48:39 +08:00
liuye
d32f771452 30731 2022-08-02 14:36:48 +08:00
yanran200730
1ddb0a1149 bug 2022-08-02 13:48:49 +08:00
yanran200730
02a30ee546 30717 2022-08-02 08:32:57 +08:00
yanran200730
a1c0de83f0 需求变更 2022-08-01 17:45:24 +08:00
yanran200730
875301eb1d 30718 2022-08-01 16:56:57 +08:00
yanran200730
8e352fa027 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-01 16:35:00 +08:00
yanran200730
874e8fa677 bug 2022-08-01 16:34:53 +08:00
liuye
ce6b11f384 宣发统计 2022-08-01 15:38:12 +08:00
liuye
ee64166f8c 宣发统计 2022-08-01 15:36:14 +08:00
yanran200730
f1fc975d79 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-01 14:24:43 +08:00
yanran200730
988c3b4c91 30693 2022-08-01 14:24:35 +08:00
liuye
068c039d47 30710 2022-08-01 14:06:04 +08:00
yanran200730
af109a9060 30706 2022-08-01 11:05:27 +08:00
yanran200730
f11e892232 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-01 11:01:15 +08:00
yanran200730
0c279f3d2e 大屏新增启用、停用功能 2022-08-01 11:01:06 +08:00
liuye
2d2da59305 css 2022-08-01 10:14:53 +08:00
yanran200730
f448d214b5 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-08-01 09:52:56 +08:00
yanran200730
d918bbe8b3 郫都大屏 2022-08-01 09:52:43 +08:00
aixianling
edcd2c19f1 Merge remote-tracking branch 'origin/dev' into dev 2022-08-01 08:56:43 +08:00
aixianling
ef38382da9 BUG 30687 2022-08-01 08:56:15 +08:00
yanran200730
e3b9eca251 bug 2022-07-29 18:39:49 +08:00
yanran200730
41faad8172 bug 2022-07-29 18:29:15 +08:00
yanran200730
8695290834 bug 2022-07-29 17:57:30 +08:00
yanran200730
7d9ec29847 30693 2022-07-29 16:48:53 +08:00
yanran200730
efc1a5a0b0 30601 2022-07-29 16:45:40 +08:00
yanran200730
5008d89ee4 30690 2022-07-29 16:27:54 +08:00
liuye
8b8e5885a0 同步成员 2022-07-29 14:22:24 +08:00
yanran200730
f834d71ca5 优化 2022-07-29 11:44:24 +08:00
yanran200730
a701d94402 bug 2022-07-29 11:42:06 +08:00
yanran200730
1a262d8859 bug 2022-07-29 11:29:09 +08:00
yanran200730
ef6009f0cc bug 2022-07-29 11:27:03 +08:00
yanran200730
aca483c7a0 bug 2022-07-29 11:25:26 +08:00
yanran200730
f1a289ca05 30665 2022-07-29 11:01:20 +08:00
yanran200730
c5e68bed86 bug 2022-07-29 10:35:44 +08:00
yanran200730
6c8071aa83 优化 2022-07-29 10:23:38 +08:00
yanran200730
6ac0b993ba Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-07-29 10:01:08 +08:00
yanran200730
0d18199cdf 郫都大屏 2022-07-29 10:01:00 +08:00
liuye
b532e9ce90 30680 2022-07-29 09:59:28 +08:00
aixianling
2cb1dc69df Merge remote-tracking branch 'origin/dev' into dev 2022-07-29 09:14:14 +08:00
aixianling
be079b0615 提取背景图,并埋点 2022-07-29 09:13:55 +08:00
liuye
d91e5ed550 显示部门+数字 2022-07-28 17:39:07 +08:00
liuye
20455c96d3 显示数字 2022-07-28 17:38:01 +08:00
liuye
f595909d73 test 2022-07-28 17:27:08 +08:00
liuye
0d77f909b8 只显示数字 2022-07-28 17:26:07 +08:00
liuye
b87c13c233 test 2022-07-28 17:17:24 +08:00
liuye
11ff8c8405 test 2022-07-28 17:11:00 +08:00
liuye
791e4d829b test 2022-07-28 17:03:57 +08:00
liuye
201cc49865 test 2022-07-28 16:56:43 +08:00
liuye
ea622b0378 test 2022-07-28 16:47:36 +08:00
liuye
e66d26f195 test 2022-07-28 16:44:05 +08:00
liuye
ab23f91b7c test 2022-07-28 16:24:16 +08:00
liuye
31231817b6 test 2022-07-28 16:22:53 +08:00
liuye
61ba2521e4 test 2022-07-28 16:11:33 +08:00
liuye
d34889997b test 2022-07-28 15:50:50 +08:00
liuye
e96726b8de Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-07-28 15:31:15 +08:00
liuye
84c679941c 打印data 2022-07-28 15:30:53 +08:00
yanran200730
f794bc6ab0 优化 2022-07-28 14:26:55 +08:00
yanran200730
471d00b47c 30663 2022-07-28 13:46:04 +08:00
yanran200730
fe44893e15 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-07-28 13:43:52 +08:00
yanran200730
b6cab0818c 30643 2022-07-28 13:43:45 +08:00
liuye
3bd3fb4950 type 2022-07-28 12:00:15 +08:00
yanran200730
e0e0329cfe Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-07-28 11:10:19 +08:00
yanran200730
4abe2b7bf5 30657 2022-07-28 11:10:11 +08:00
liuye
ec70dc13bc 宣发统计 2022-07-28 10:52:45 +08:00
liuye
19c20944e4 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-07-28 10:48:33 +08:00
liuye
e5d1e8eb55 echart部门id转换 2022-07-28 10:48:02 +08:00
yanran200730
a1b4574bae 30648 2022-07-28 10:45:07 +08:00
aixianling
720adb7e86 引导页图片资源往oms的服务器上传 2022-07-28 10:02:43 +08:00
aixianling
b8c7e03f29 Merge remote-tracking branch 'origin/dev' into dev 2022-07-27 17:32:58 +08:00
aixianling
2a8d1f17a5 实时渲染 2022-07-27 17:32:43 +08:00
yanran200730
9d0047e071 30636 2022-07-27 17:25:40 +08:00
yanran200730
fb491446c7 30574 2022-07-27 17:23:14 +08:00
yanran200730
3f4633677b Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-07-27 17:19:49 +08:00
yanran200730
d7f0b63eb9 30638 2022-07-27 17:19:42 +08:00
aixianling
32eaae40d7 消除错误异常 2022-07-27 17:09:40 +08:00
aixianling
36f516c037 Merge remote-tracking branch 'origin/dev' into dev 2022-07-27 17:00:02 +08:00
aixianling
663ddc8386 全屏展示 2022-07-27 16:59:45 +08:00
liuye
253d90b15a Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-07-27 16:53:52 +08:00
liuye
94b86e2a0b 30634 写死 群发居民群 2022-07-27 16:53:03 +08:00
yanran200730
b3f0ed96e9 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-07-27 16:17:27 +08:00
yanran200730
9e6532194f 30612 2022-07-27 16:17:20 +08:00
aixianling
c5e2bef011 Merge remote-tracking branch 'origin/dev' into dev 2022-07-27 15:59:33 +08:00
aixianling
4b3e287a5f 主题设置页面完成 2022-07-27 15:59:13 +08:00
yanran200730
b89e7db2a2 30628 2022-07-27 15:51:08 +08:00
yanran200730
0dcc74b567 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-07-27 15:49:56 +08:00
yanran200730
5b128adddb 30626 2022-07-27 15:49:48 +08:00
liuye
17f59a1954 30611时间回显 2022-07-27 15:08:30 +08:00
yanran200730
9b24504528 30609 2022-07-27 14:52:40 +08:00
yanran200730
aafcec25fb 30612 2022-07-27 14:50:58 +08:00
yanran200730
8f1c25043d Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-07-27 14:47:24 +08:00
yanran200730
26f5483182 30605 2022-07-27 14:47:17 +08:00
liuye
4cd600d285 bug 2022-07-27 14:34:57 +08:00
aixianling
ac1d17c216 联合调整 2022-07-27 14:26:26 +08:00
yanran200730
4f62c5cb9d Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-07-27 11:23:07 +08:00
yanran200730
658a29853b 30603 2022-07-27 11:22:56 +08:00
liuye
a35a78ef00 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-07-27 10:54:10 +08:00
liuye
6d3fe01c99 30584 2022-07-27 10:53:55 +08:00
yanran200730
aa6579d040 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-07-27 10:36:32 +08:00
yanran200730
d57890c0a9 30600 2022-07-27 10:36:21 +08:00
aixianling
cf99b2730a 增加路由展示 2022-07-27 10:31:56 +08:00
aixianling
9997f732dc Merge remote-tracking branch 'origin/dev' into dev 2022-07-27 10:25:00 +08:00
aixianling
3329cd4bf1 去除formatContent 2022-07-27 10:24:38 +08:00
yanran200730
f16f3457dd bug 2022-07-27 10:17:10 +08:00
yanran200730
2282183509 路由跳转 2022-07-27 10:04:48 +08:00
yanran200730
5cb525d9a2 30595 2022-07-27 09:55:23 +08:00
yanran200730
7f82c5b4cf 30569 2022-07-27 09:14:27 +08:00
yanran200730
f4d64555d0 30570 2022-07-26 18:05:45 +08:00
yanran200730
7813ddb003 30576 2022-07-26 18:02:03 +08:00
yanran200730
3eff2139dc 30577 2022-07-26 17:57:18 +08:00
yanran200730
b5c85e0031 bug 2022-07-26 17:55:40 +08:00
yanran200730
8d727d4f39 30571 2022-07-26 17:42:21 +08:00
yanran200730
b2002d5989 30572 2022-07-26 17:37:15 +08:00
yanran200730
4f357b1dd4 bug 2022-07-26 15:20:20 +08:00
yanran200730
d85ab06f68 郫都大屏 2022-07-26 15:09:46 +08:00
yanran200730
f0099ecd92 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-07-26 09:43:29 +08:00
yanran200730
d5a20de52b bug 2022-07-26 09:43:22 +08:00
aixianling
7101bdff2c Merge remote-tracking branch 'origin/dev' into dev 2022-07-26 09:34:20 +08:00
aixianling
2831c8b5af 接口兼容 2022-07-26 09:34:00 +08:00
yanran200730
d896db5d4d 协同宣发 2022-07-26 09:26:54 +08:00
liuye
59db5a1568 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-07-25 17:54:16 +08:00
yanran200730
7dc3032824 协同宣发 2022-07-25 17:53:53 +08:00
liuye
28bba07f22 宣发统计 2022-07-25 17:51:59 +08:00
yanran200730
5da0f4b651 bug 2022-07-25 16:38:05 +08:00
yanran200730
07fac1c94e 协同宣发 优化 2022-07-25 15:40:13 +08:00
yanran200730
f1f8b2bf93 协同宣发 接口对接 2022-07-25 15:07:23 +08:00
yanran200730
f89deadcb2 宣发统计 2022-07-25 14:10:51 +08:00
yanran200730
bd3ef507cc 协同宣发 2022-07-25 11:36:38 +08:00
liuye
12c6d325ce Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-07-25 10:51:15 +08:00
liuye
7063fd5cd9 id转文字 2022-07-25 10:50:59 +08:00
yanran200730
e051460e31 协同宣发 2022-07-25 10:39:51 +08:00
yanran200730
4413821d1b bug 2022-07-22 14:54:45 +08:00
yanran200730
0eb642a625 bug 2022-07-22 14:44:55 +08:00
yanran200730
04beb515d0 bug 2022-07-22 14:19:59 +08:00
yanran200730
5996377c2d bug 2022-07-22 14:13:07 +08:00
yanran200730
74c47dcba0 bug 2022-07-22 14:01:36 +08:00
yanran200730
db07381bbd bug 2022-07-22 13:49:43 +08:00
yanran200730
a170cf7b1f bug 2022-07-22 13:46:02 +08:00
yanran200730
156bdba217 大屏 2022-07-22 13:45:09 +08:00
yanran200730
34afcbf84e Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-07-22 11:54:46 +08:00
yanran200730
aae17797b7 大屏 2022-07-22 11:53:58 +08:00
aixianling
65e49790e8 Merge remote-tracking branch 'origin/dev' into dev 2022-07-22 10:32:20 +08:00
aixianling
0ab2a0f5b7 追加字典初始化 2022-07-22 10:32:02 +08:00
yanran200730
d9e1f83d05 bug 2022-07-22 08:53:00 +08:00
yanran200730
cf18beb6dc bug 2022-07-22 08:36:11 +08:00
yanran200730
fe09fa4983 大屏 2022-07-21 19:04:54 +08:00
yanran200730
7a310007b1 大屏 2022-07-21 18:33:21 +08:00
yanran200730
f5abfa0084 bug 2022-07-21 18:28:55 +08:00
yanran200730
d7b7de09f7 bug 2022-07-21 18:22:58 +08:00
yanran200730
c1131c0b54 大屏 2022-07-21 18:19:47 +08:00
yanran200730
2f05a88e56 大屏 2022-07-21 17:44:49 +08:00
yanran200730
b804a7e5aa 大屏 2022-07-21 17:36:09 +08:00
yanran200730
73080b55f8 大屏 2022-07-21 17:20:05 +08:00
yanran200730
5e5e0d9b57 大屏 2022-07-21 16:50:53 +08:00
yanran200730
552c6888e5 大屏 2022-07-21 15:07:15 +08:00
yanran200730
d650dedcb6 大屏 2022-07-21 14:33:10 +08:00
yanran200730
e85ef5ff6f 大屏 2022-07-21 13:58:28 +08:00
yanran200730
2d53a8a31d 宣发 2022-07-21 09:38:02 +08:00
yanran200730
12bb196de3 bug 2022-07-20 18:04:10 +08:00
yanran200730
a29a934e95 协同宣发 2022-07-20 16:36:29 +08:00
liuye
8aee36e808 宣发统计 2022-07-20 14:25:28 +08:00
liuye
0fa2950bb7 选择部门 2022-07-20 10:22:22 +08:00
yanran200730
68e26624be 宣发 2022-07-19 17:31:27 +08:00
liuye
c29d493159 日历 2022-07-19 16:11:06 +08:00
liuye
837c31abeb Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-07-19 15:24:32 +08:00
liuye
1836d989ca 日历 2022-07-19 15:24:23 +08:00
aixianling
d1c92c569f 整合通讯录组件渲染 2022-07-19 15:20:10 +08:00
aixianling
d58b590200 Merge remote-tracking branch 'origin/dev' into dev 2022-07-19 14:56:13 +08:00
aixianling
b5a0522fb9 整合通讯录组件渲染 2022-07-19 14:55:51 +08:00
yanran200730
62f92569b3 协同宣发 2022-07-19 10:58:21 +08:00
yanran200730
6d50374606 宣发 2022-07-19 10:02:58 +08:00
liuye
4b67e33ae9 自定义时间选择 2022-07-19 09:43:11 +08:00
yanran200730
a5bc5689a3 宣发 2022-07-18 17:15:01 +08:00
aixianling
bd410a9559 修复接口调用 2022-07-18 14:46:00 +08:00
aixianling
351667a8a0 应用,我的入库 2022-07-15 19:03:58 +08:00
aixianling
1c40a78bae 首页入库 2022-07-15 18:42:59 +08:00
aixianling
d388123410 首页入库 2022-07-15 18:12:50 +08:00
liuye
2d307db6ce Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-07-15 17:39:57 +08:00
liuye
09974cb43b 宣发日历 2022-07-15 17:39:36 +08:00
yanran200730
ed9a206ad6 bug 2022-07-15 14:37:09 +08:00
yanran200730
8317137068 1 2022-07-15 10:40:05 +08:00
aixianling
edda197051 Merge remote-tracking branch 'origin/dev' into dev 2022-07-14 18:00:24 +08:00
aixianling
5e91aee82e 定制方案全新升级 2022-07-14 18:00:07 +08:00
liuye
1bfe8afc8b 宣发日历 2022-07-14 17:10:58 +08:00
aixianling
a6cd4d2578 BUG 30542 2022-07-14 16:56:36 +08:00
aixianling
c6f7d4e449 优化小程序发布 2022-07-14 14:53:40 +08:00
yanran200730
ea4f22c2b9 群发 2022-07-14 14:00:31 +08:00
aixianling
a50c9ce240 优化展示 2022-07-14 12:01:12 +08:00
aixianling
0f03dc9d04 进村入库,修复定制方案的BUG 2022-07-14 11:52:00 +08:00
aixianling
4b4baf4952 贷款审批默认审核状态为待审批 2022-07-14 11:16:12 +08:00
aixianling
baccd4505b 定制方案小程序完成 2022-07-14 10:11:17 +08:00
aixianling
7ee49a5367 Merge remote-tracking branch 'origin/dev' into dev 2022-07-14 09:05:26 +08:00
aixianling
6522a101ea BUG 30542 2022-07-14 09:04:25 +08:00
yanran200730
f114c9497a 协同宣发 2022-07-13 18:15:32 +08:00
yanran200730
20c61297c6 协同宣发 2022-07-13 16:54:03 +08:00
aixianling
2bf8c5d150 Merge remote-tracking branch 'origin/dev' into dev 2022-07-13 16:25:18 +08:00
aixianling
8b133291a4 驻村辅警迁移至山东版本 2022-07-13 16:25:02 +08:00
liuye
980f8e1f5a Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-07-13 16:06:32 +08:00
liuye
0cec1b0a20 宣发日历 2022-07-13 16:06:10 +08:00
aixianling
1e64e12d49 AiDialogBtn升级到UI库 2022-07-13 15:17:35 +08:00
yanran200730
f529e4bb32 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-07-13 12:01:29 +08:00
yanran200730
c8a3e74ae5 bug 2022-07-13 12:01:18 +08:00
aixianling
a2fa966ccd Merge remote-tracking branch 'origin/dev' into dev 2022-07-13 11:09:25 +08:00
aixianling
7d0fd6b907 应用库搜索优化 2022-07-13 11:09:06 +08:00
yanran200730
6b1797e36d 协同宣发 2022-07-13 10:54:26 +08:00
aixianling
9764c831d7 Merge remote-tracking branch 'origin/dev' into dev 2022-07-13 10:48:30 +08:00
aixianling
53bf46fac5 添加应用分类字典,增加定制方案应用概览 2022-07-13 10:48:15 +08:00
yanran200730
fb8ea2a195 协同宣发 2022-07-13 09:13:41 +08:00
yanran200730
cebe4ce80f bug 2022-07-13 08:34:45 +08:00
aixianling
031faeff50 小程序构建模式初步规划 2022-07-12 18:25:42 +08:00
aixianling
422dcdc6be 多选优化,可以全选了 2022-07-12 18:13:13 +08:00
aixianling
7d63ea0c19 定制项目调整定位为定制方案 2022-07-12 16:49:41 +08:00
aixianling
ad8f080643 增加快速启动的研发模式fast 2022-07-12 16:43:32 +08:00
aixianling
44bd3c95c3 配置引导页完成 2022-07-11 17:00:58 +08:00
aixianling
86451a245f 配置引导页完成一部分 2022-07-08 18:01:58 +08:00
aixianling
d12705b4f6 全量企微包 2022-07-07 18:07:21 +08:00
shijingjing
0e96395d98 fpPrtpStatus 2022-07-07 10:11:01 +08:00
aixianling
cef8dad5f0 Merge branch 'dev' into vite 2022-07-07 09:33:20 +08:00
shijingjing
5c7e2e4098 30530 2022-07-07 09:27:48 +08:00
aixianling
b8401c34c9 BUG 30527 2022-07-07 09:15:18 +08:00
aixianling
da8e8f0d65 Merge branch 'dev' into vite
# Conflicts:
#	examples/main.js
#	examples/router/autoRoutes.js
#	package.json
#	packages/bigscreen/designer/AppDesigner.vue
#	packages/bigscreen/designer/components/Add.vue
#	packages/bigscreen/designer/components/Layout.vue
#	packages/bigscreen/designer/components/List.vue
#	packages/bigscreen/designer/components/SourceData.vue
#	packages/bigscreen/designer/components/form/DataConfig.vue
#	packages/bigscreen/designer/config.js
#	packages/bigscreen/viewer/AppGigscreenViewer.vue
#	packages/conv/creditScore/scoreManage/scoreChange.vue
#	packages/index.js
#	project/dv/apps/AppGridDV.vue
#	project/dvui/components/AiMonitor/dhVideo.vue
#	project/dvui/components/AiSwiper.vue
#	project/dvui/layout/AiDvBackground.vue
#	project/dvui/layout/AiDvSummary/AiDvSummary.vue
#	project/dvui/layout/AiDvWrapper/AiDvWrapper.vue
#	project/dvui/package.json
#	public/index.html
#	vue.config.js
2022-07-07 09:01:40 +08:00
shijingjing
92f8fd0af8 bug 2022-07-06 18:25:49 +08:00
aixianling
e3626ea7ba BUG 30521 2022-07-06 18:06:36 +08:00
aixianling
7c3620eea1 BUG 30518 2022-07-06 17:58:53 +08:00
aixianling
dd4b58312e BUG 30522 2022-07-06 17:20:58 +08:00
aixianling
d87c947ca1 BUG 30522 2022-07-06 16:50:12 +08:00
aixianling
83580d9ef3 BUG 30522 2022-07-06 16:49:35 +08:00
aixianling
8db4f1bb30 BUG 30522 2022-07-06 16:49:04 +08:00
aixianling
2c1430b88a BUG 29625 2022-07-06 16:09:55 +08:00
aixianling
7a0d0322da BUG 30520 2022-07-06 15:52:23 +08:00
aixianling
67b9c61eef BUG 30385 2022-07-06 15:50:28 +08:00
aixianling
37ea4d4db6 BUG 30521 2022-07-06 15:15:16 +08:00
aixianling
bcd90e0706 BUG 30508 2022-07-06 15:14:23 +08:00
aixianling
108c486240 BUG 30503 2022-07-06 15:02:48 +08:00
aixianling
489b39f9e6 BUG 29591 2022-07-06 14:55:34 +08:00
aixianling
6e3f72092c BUG 30518 2022-07-06 14:49:34 +08:00
aixianling
292b4720e3 BUG 30510 2022-07-06 14:26:45 +08:00
aixianling
eb408e0bfb 整合 2022-07-06 12:08:28 +08:00
aixianling
83a30fda7d BUG 30501 2022-07-06 11:42:39 +08:00
aixianling
88ac20bbcd 金融产品增加办理渠道 2022-07-06 11:39:24 +08:00
aixianling
e73641d6de Merge remote-tracking branch 'origin/dev' into dev 2022-07-06 11:12:43 +08:00
aixianling
d57fd8a7a2 BUG 30387 2022-07-06 11:12:15 +08:00
shijingjing
62752263c0 30499 2022-07-06 10:20:07 +08:00
shijingjing
2f5aba907e 工作考核 2022-07-05 17:05:45 +08:00
aixianling
2a924caacd 信用=>信息 2022-07-05 17:01:46 +08:00
aixianling
8eb0c51937 信用报告完成 2022-07-05 16:59:28 +08:00
aixianling
9693df6e26 完善产品库 2022-07-05 16:08:00 +08:00
aixianling
f8105d5422 完善产品库 2022-07-05 16:05:58 +08:00
aixianling
2f351dbd68 信用报告下载完成 2022-07-05 15:23:25 +08:00
aixianling
7ee368e6db Merge remote-tracking branch 'origin/dev' into dev 2022-07-05 15:10:19 +08:00
aixianling
a75c2d254f 信用报告查询完成 2022-07-05 15:09:53 +08:00
shijingjing
86b1349a46 bug 2022-07-05 10:58:43 +08:00
aixianling
5219ca9a3f 修复下锁屏未关闭的问题 2022-07-04 15:47:44 +08:00
aixianling
f67bdea66f 定制项目提交一波 2022-07-04 15:13:36 +08:00
aixianling
7cf7d41c23 定制项目提交一波 2022-07-04 14:48:21 +08:00
shijingjing
d046ca1dd6 监测对象 2022-07-04 14:24:27 +08:00
shijingjing
e02aad528e 30487 2022-07-04 14:21:57 +08:00
aixianling
b0f0e693aa Merge remote-tracking branch 'origin/dev' into dev 2022-07-04 14:16:24 +08:00
aixianling
59d0a80043 定制项目提交一波 2022-07-04 14:16:07 +08:00
shijingjing
0d5a9fed10 30486 2022-07-04 14:13:55 +08:00
aixianling
3e87d2afca 增加通讯录同步 2022-07-04 11:49:07 +08:00
aixianling
acb8bd9d1c 回复调整 2022-07-04 10:46:39 +08:00
aixianling
52485cb63e 调解link 2022-07-04 10:46:03 +08:00
aixianling
8e31b662ce 定制项目模块界面完成 2022-07-01 18:26:52 +08:00
aixianling
a632cefb3b 修复低代码平台 2022-07-01 18:00:00 +08:00
shijingjing
96b7c8bbeb 30450 30461 2022-07-01 14:55:59 +08:00
shijingjing
9c61fde48d 阶梯 2022-07-01 14:49:33 +08:00
aixianling
065e474c86 Merge remote-tracking branch 'origin/dev' into dev 2022-07-01 14:09:08 +08:00
aixianling
9e0f38c0e3 BUG 30390 2022-07-01 14:08:41 +08:00
shijingjing
7dd7e6483c 权限码 2022-07-01 14:03:14 +08:00
aixianling
0dc6a67f9f Merge remote-tracking branch 'origin/dev' into dev 2022-07-01 14:02:18 +08:00
aixianling
4a3063bd8c BUG 30385 2022-07-01 14:01:19 +08:00
shijingjing
efb7ebeeee 去掉权限码 2022-07-01 13:59:37 +08:00
shijingjing
792d270446 判断 2022-07-01 13:43:25 +08:00
shijingjing
59f8671e90 total 2022-07-01 12:34:19 +08:00
shijingjing
da929c20a2 漏了 2022-07-01 11:24:31 +08:00
shijingjing
4be5825cf1 push 2022-07-01 11:23:08 +08:00
shijingjing
e9d5e63a3e bug 2022-07-01 11:11:58 +08:00
shijingjing
cd76b41ba7 bug 2022-07-01 10:22:03 +08:00
shijingjing
53daf5309b 30459 2022-07-01 09:48:26 +08:00
shijingjing
0b0b15fd55 30465 2022-07-01 09:41:51 +08:00
shijingjing
d8f13f09c5 30411 2022-07-01 09:23:55 +08:00
shijingjing
fc7067cff3 bug 2022-06-30 21:35:22 +08:00
shijingjing
0ec77d5a48 bug 2022-06-30 21:22:29 +08:00
shijingjing
9d36bbbf06 bug 2022-06-30 20:44:27 +08:00
shijingjing
6a09277e2b 30462 2022-06-30 20:42:20 +08:00
shijingjing
fa6ea7a9b3 30461 2022-06-30 20:41:03 +08:00
shijingjing
1b55f8d643 bug 2022-06-30 20:30:34 +08:00
shijingjing
4e3632e4b5 30451 2022-06-30 20:17:20 +08:00
shijingjing
de03942d0e 30459 2022-06-30 20:14:58 +08:00
shijingjing
6bfc039364 30413 2022-06-30 20:06:48 +08:00
shijingjing
21e1fa71b8 30453 2022-06-30 20:05:02 +08:00
shijingjing
4db8628b87 30448 2022-06-30 20:01:50 +08:00
shijingjing
b784d81020 30447 2022-06-30 20:00:01 +08:00
shijingjing
62b5ff4458 30443 2022-06-30 19:49:26 +08:00
shijingjing
324edf7569 30442 2022-06-30 19:42:27 +08:00
shijingjing
c17cebfe2a 30441 2022-06-30 19:29:07 +08:00
shijingjing
33e38db789 30440 2022-06-30 19:26:51 +08:00
shijingjing
1c2381c9b1 30437 2022-06-30 19:25:59 +08:00
shijingjing
071bd9daf5 30418 2022-06-30 19:21:09 +08:00
shijingjing
5d2c1279d8 党员积分 2022-06-30 18:39:39 +08:00
shijingjing
bb7406c7c9 30425 2022-06-30 18:02:37 +08:00
shijingjing
36ccc9ace2 30421 2022-06-30 17:43:14 +08:00
shijingjing
d8c652762a 30413 2022-06-30 17:23:50 +08:00
shijingjing
10ded04b7d no message 2022-06-30 17:18:18 +08:00
shijingjing
9587b1acfe 30398 2022-06-30 16:59:55 +08:00
shijingjing
a08aca7afe 30395 2022-06-30 16:31:52 +08:00
shijingjing
7a0ae3143b 30394 2022-06-30 16:29:50 +08:00
shijingjing
b29ddfc2fc 30392 30392 2022-06-30 16:24:42 +08:00
shijingjing
555a888ab7 auditIntegralItem字段 2022-06-30 15:56:13 +08:00
shijingjing
27afc15796 30404 2022-06-30 15:51:18 +08:00
shijingjing
d601b1d4c2 30406 2022-06-30 15:46:49 +08:00
shijingjing
844fad5301 30406 2022-06-30 15:27:00 +08:00
aixianling
1c9490427b 增加指定npm脚本构建选项 2022-06-30 15:24:36 +08:00
aixianling
f80c5a3b41 恢复标准版 2022-06-30 13:58:57 +08:00
shijingjing
fbd7680927 bug 2022-06-30 11:57:34 +08:00
shijingjing
392ba406bc 党员积分 2022-06-30 11:41:57 +08:00
shijingjing
0e15dca25b 日期 2022-06-30 11:27:46 +08:00
shijingjing
d53bc8fe20 积分维护 2022-06-30 11:25:47 +08:00
aixianling
3d1e68b29d 修复大屏设计滚动 2022-06-30 10:17:05 +08:00
aixianling
2c00ad961c Merge remote-tracking branch 'origin/dev' into dev 2022-06-30 10:14:15 +08:00
shijingjing
6ecad30626 编辑 2022-06-30 10:14:10 +08:00
aixianling
9ccf4e2a3b 修复相同appid不同版本数据混淆问题 2022-06-30 10:14:01 +08:00
shijingjing
6de41e883a name 2022-06-30 10:05:00 +08:00
shijingjing
584eec0e78 三涧溪党员积分 2022-06-30 09:56:49 +08:00
shijingjing
3624b48511 积分审核 2022-06-29 19:02:10 +08:00
shijingjing
47ce4ba424 党员积分 2022-06-29 18:50:57 +08:00
shijingjing
39f5bcbd5a 积分维护 2022-06-29 18:44:06 +08:00
shijingjing
d7568eb799 积分规则 2022-06-29 17:57:36 +08:00
shijingjing
0f3276ceca label 2022-06-29 16:07:06 +08:00
shijingjing
ef6855c3a6 积分规则 积分维护 2022-06-29 16:05:30 +08:00
aixianling
fdf441c8e8 BUG 30384 2022-06-29 14:03:58 +08:00
aixianling
d4bb5d2de0 BUG 30357 2022-06-29 14:03:07 +08:00
shijingjing
bc1f9ba4cb 积分 2022-06-29 10:17:54 +08:00
刘仕伟
024cb5831b Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-06-28 18:18:46 +08:00
刘仕伟
84bf07717a 设备配置 2022-06-28 18:18:43 +08:00
aixianling
cc211cd22b 优化大屏组件 2022-06-28 18:18:37 +08:00
刘仕伟
b117cf9d51 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-06-28 16:13:09 +08:00
刘仕伟
8341473672 设备配置页面调整 2022-06-28 16:13:03 +08:00
shijingjing
d021781d75 经办人 2022-06-28 16:05:19 +08:00
aixianling
059da71d6d 优化第三方包加载 2022-06-28 16:04:04 +08:00
aixianling
52c62f7955 大屏支持渲染3D模型 2022-06-28 16:02:37 +08:00
aixianling
352ae43faa 大屏支持渲染3D模型 2022-06-28 15:48:12 +08:00
aixianling
361792c48d 集中升级 2022-06-28 15:37:13 +08:00
aixianling
2b248b0177 BUG 30381 2022-06-28 15:28:36 +08:00
刘仕伟
d923fd5420 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-06-28 15:08:20 +08:00
刘仕伟
92d5b99384 查询条件 2022-06-28 15:08:13 +08:00
aixianling
315d852eaf BUG 30381 2022-06-28 15:03:50 +08:00
aixianling
e1760adf4e Merge remote-tracking branch 'origin/dev' into dev 2022-06-28 14:55:08 +08:00
aixianling
f69550c015 BUG 30380 2022-06-28 14:54:50 +08:00
刘仕伟
393846b836 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-06-28 14:42:55 +08:00
刘仕伟
18e4ffa7a1 列表调整 2022-06-28 14:42:51 +08:00
aixianling
0056a31dcb 清理门户,删除垃圾依赖库 2022-06-28 14:37:48 +08:00
aixianling
40ebb8630a Merge remote-tracking branch 'origin/dev' into dev 2022-06-28 14:25:30 +08:00
aixianling
d51918b713 升级大屏组件 2022-06-28 14:25:12 +08:00
刘仕伟
51d2b8eaf9 设备配置 2022-06-28 14:20:35 +08:00
liuye
1605d280b8 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-06-28 11:54:32 +08:00
liuye
7ae4e92a93 设备管理 2022-06-28 11:53:49 +08:00
aixianling
d5fe146cec BUG 30376 2022-06-28 11:42:55 +08:00
aixianling
f239508b87 BUG 30358 2022-06-28 11:19:02 +08:00
aixianling
a6924dac90 Merge remote-tracking branch 'origin/dev' into dev 2022-06-28 11:16:25 +08:00
aixianling
9ea41700c7 BUG 30357 2022-06-28 11:16:08 +08:00
liuye
09cced8bc3 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-06-28 10:40:43 +08:00
liuye
4b893b6c49 设备管理 2022-06-28 10:40:13 +08:00
shijingjing
6eb7b5d13d 30377 2022-06-28 10:36:31 +08:00
liuye
781c0f1543 fix 2022-06-28 09:15:35 +08:00
liuye
b9964d64b0 fix 2022-06-28 09:15:10 +08:00
liuye
6896dfd197 fix 2022-06-28 09:14:39 +08:00
aixianling
e0221ae9ee BUG 30351 2022-06-27 18:03:37 +08:00
aixianling
d212d1ea1f Merge remote-tracking branch 'origin/dev' into dev 2022-06-27 17:56:49 +08:00
aixianling
513db9b4b9 BUG 30350 2022-06-27 17:56:32 +08:00
shijingjing
4b93111ae0 30371 2022-06-27 17:54:50 +08:00
aixianling
bfa2985b2f Merge remote-tracking branch 'origin/dev' into dev 2022-06-27 17:42:03 +08:00
aixianling
0ac30e762e BUG 30372 2022-06-27 17:41:44 +08:00
shijingjing
d5fadfc498 格式化 2022-06-27 17:33:31 +08:00
aixianling
7b3fcef56e BUG 30360 2022-06-27 17:22:52 +08:00
shijingjing
a9e4aae662 30355 2022-06-27 14:37:00 +08:00
shijingjing
0a154f0c1f 30346 2022-06-27 11:17:22 +08:00
shijingjing
a59a96b092 30344 2022-06-27 11:10:14 +08:00
yanran200730
ed30be74bc Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-06-27 11:01:04 +08:00
yanran200730
96aec2e69f bug 2022-06-27 11:00:52 +08:00
aixianling
6e5a1c3921 BUG 30340 2022-06-27 10:45:29 +08:00
shijingjing
aa846b62a7 bug 30322 2022-06-27 10:34:15 +08:00
yanran200730
b5ae298ee9 bug 2022-06-27 09:43:09 +08:00
shijingjing
a3cb513b57 删除多余代码 2022-06-27 09:03:16 +08:00
aixianling
54127cc668 Merge remote-tracking branch 'origin/dev' into dev 2022-06-27 08:55:21 +08:00
aixianling
3e466e01cb BUG 30330 2022-06-27 08:54:51 +08:00
shijingjing
47b681c99d 列表 详情 2022-06-24 23:21:18 +08:00
aixianling
a1ca224a98 完成 2022-06-24 23:12:16 +08:00
aixianling
07bc1389c1 Merge remote-tracking branch 'origin/dev' into dev
# Conflicts:
#	packages/wxwork/AppMassNotification/components/Add.vue
#	packages/wxwork/AppMassNotification/components/List.vue
2022-06-24 20:52:39 +08:00
aixianling
9292429c8c 页面整合 2022-06-24 20:50:47 +08:00
shijingjing
356758a184 群发 2022-06-24 20:45:45 +08:00
aixianling
d979943852 BUG 29877 2022-06-24 20:41:54 +08:00
aixianling
8a7d6f746f BUG 30302 2022-06-24 19:58:27 +08:00
aixianling
6deb734d94 Merge remote-tracking branch 'origin/dev' into dev 2022-06-24 17:04:21 +08:00
aixianling
e55e0fc2cc 大屏应用位置整合 2022-06-24 17:03:35 +08:00
shijingjing
d8817261ca 群发消息 2022-06-24 15:08:02 +08:00
aixianling
8e04ec040a 大屏应用位置整合 2022-06-24 13:51:32 +08:00
aixianling
05db88644c 秀山需求变更 2022-06-23 16:54:06 +08:00
aixianling
90ab2dec01 秀山需求变更 2022-06-23 15:58:25 +08:00
aixianling
16128af70f 秀山需求变更 2022-06-23 14:59:54 +08:00
aixianling
1a3827e541 样式整合 2022-06-23 14:28:48 +08:00
aixianling
cc283155a1 BUG 30299 2022-06-23 14:00:34 +08:00
aixianling
a751e3e70b 修复异常 2022-06-23 11:06:48 +08:00
aixianling
3b58dec324 增加手动控制取消打包 2022-06-23 10:29:59 +08:00
aixianling
503416902c BUG 30288 2022-06-22 17:45:00 +08:00
aixianling
1c54bac79c 低代码前端完成 2022-06-22 16:54:27 +08:00
aixianling
ff322874e2 低代码前端完成 2022-06-22 11:24:21 +08:00
aixianling
03bd52194b 低代码前端完成 2022-06-22 11:20:42 +08:00
aixianling
17e2d3b12a Merge remote-tracking branch 'origin/dev' into dev 2022-06-22 11:09:13 +08:00
aixianling
834132fec2 低代码前端完成 2022-06-22 11:08:55 +08:00
yanran200730
e7e69d72e3 bug 2022-06-22 10:56:41 +08:00
shijingjing
98762e996c instance 2022-06-22 09:13:47 +08:00
shijingjing
11e8588e0d css 2022-06-22 08:43:38 +08:00
shijingjing
0ac92994bc 视频 2022-06-21 18:52:25 +08:00
shijingjing
3ac9250f38 屏蔽居民统计 2022-06-21 14:22:45 +08:00
shijingjing
340e40b6d1 党员积分明细 2022-06-21 10:58:33 +08:00
aixianling
87215e6352 Merge remote-tracking branch 'origin/dev' into dev 2022-06-20 18:31:47 +08:00
aixianling
d3aa3eef94 低代码平台 2022-06-20 18:31:30 +08:00
shijingjing
7db8828e0b 积分 2022-06-20 17:44:13 +08:00
shijingjing
25b4572ec8 添加积分规则 2022-06-20 16:59:20 +08:00
shijingjing
5f208c4510 积分审核 2022-06-20 14:52:15 +08:00
shijingjing
c378806112 积分明细 2022-06-20 14:25:33 +08:00
shijingjing
dd9394b9eb 党员积分 2022-06-20 13:48:16 +08:00
aixianling
169c3afc06 Merge remote-tracking branch 'origin/dev' into dev 2022-06-20 11:40:00 +08:00
aixianling
4567edbd5f 增加本地调试配置 2022-06-20 11:39:43 +08:00
shijingjing
387b25c678 积分管理 2022-06-20 11:26:42 +08:00
aixianling
918b88e5e2 优化设置 2022-06-20 11:01:12 +08:00
aixianling
b66d14f53e 迁移位置 2022-06-20 10:24:39 +08:00
aixianling
c7c72ddd26 Merge remote-tracking branch 'origin/dev' into dev 2022-06-20 10:03:22 +08:00
aixianling
c03be59b18 迁移位置 2022-06-20 10:03:03 +08:00
6b80930bc0 变更字段说明 2022-06-19 22:30:03 +08:00
aixianling
768304bf9d 优化打包脚本,自动构建打包 2022-06-17 18:42:59 +08:00
aixianling
3e2a01339d 增加打包功能 2022-06-17 11:29:49 +08:00
aixianling
7b70dafbaf 增加打包功能 2022-06-17 11:25:26 +08:00
aixianling
62248f1ac6 BUG 30199 2022-06-16 17:56:42 +08:00
aixianling
ddc87afed2 BUG 30199 2022-06-16 17:43:18 +08:00
shijingjing
531f1a55fd 其他类型 2022-06-16 17:02:53 +08:00
aixianling
db71cb58d3 Merge remote-tracking branch 'origin/dev' into dev 2022-06-16 15:31:53 +08:00
aixianling
345f1c10b0 更新部署打包 2022-06-16 15:31:40 +08:00
yanran200730
f95dc9adcc Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-06-16 14:01:23 +08:00
yanran200730
3dce3cd497 网格大屏bug 2022-06-16 14:01:17 +08:00
aixianling
fb44d8888a Merge remote-tracking branch 'origin/dev' into dev 2022-06-16 13:48:21 +08:00
aixianling
ca38041eec BUG 30204 2022-06-16 13:48:07 +08:00
yanran200730
2dbdc7a4c4 网格大屏需求变更 2022-06-16 11:47:08 +08:00
yanran200730
942078e3fd 数据源管理 2022-06-16 11:29:22 +08:00
yanran200730
5bc5bf0672 大屏 2022-06-16 11:21:30 +08:00
yanran200730
307f835cec 去除九分屏 2022-06-16 10:57:55 +08:00
shijingjing
a5bfb77e2a 群发通知 2022-06-15 16:18:57 +08:00
aixianling
fd755fa58a Merge remote-tracking branch 'origin/dev' into dev 2022-06-15 09:49:14 +08:00
aixianling
318b7d7748 BUG 30199 2022-06-15 09:48:53 +08:00
shijingjing
ffd792acaa bug 2022-06-14 17:37:10 +08:00
aixianling
7f76715aeb 秀山需求变更完成 2022-06-14 16:11:55 +08:00
aixianling
c09236b06f Merge remote-tracking branch 'origin/dev' into dev 2022-06-14 15:15:11 +08:00
aixianling
00142f0935 秀山端口调整39896 2022-06-14 15:14:53 +08:00
shijingjing
190afb8d9d 消息群发 2022-06-14 14:47:49 +08:00
shijingjing
447a9703ac 消息类容 2022-06-14 14:39:52 +08:00
shijingjing
7235fd4834 消息群发 2022-06-14 14:04:00 +08:00
shijingjing
dc44b85d69 调整一下 2022-06-14 09:31:16 +08:00
yanran200730
db8b9b82da 监控视频样式bug 2022-06-14 09:11:57 +08:00
shijingjing
abc33595df 消息列表 2022-06-13 22:54:51 +08:00
aixianling
bf29282de6 BUG 30031 2022-06-13 21:10:58 +08:00
shijingjing
1b07cef1d5 bug 2022-06-13 18:22:04 +08:00
shijingjing
dd8ba7e3ce 30198 2022-06-13 17:49:04 +08:00
shijingjing
d862c250fa 群发消息 2022-06-13 17:23:16 +08:00
shijingjing
8ebac73812 群发通知 2022-06-13 17:18:21 +08:00
shijingjing
e941dda29c css 2022-06-13 16:36:40 +08:00
shijingjing
f74ca9402a 户类型 2022-06-13 16:07:42 +08:00
shijingjing
08f8739a80 防返贫 2022-06-13 16:03:08 +08:00
shijingjing
4066e61fba 类型 2022-06-13 15:08:43 +08:00
shijingjing
55be902080 撤回 - 30158 2022-06-13 14:50:39 +08:00
aixianling
2c2bc040ca Merge remote-tracking branch 'origin/dev' into dev 2022-06-13 14:32:58 +08:00
aixianling
a3f5bc03d0 BUG 30150 2022-06-13 14:32:40 +08:00
shijingjing
2f1e902885 状态 2022-06-13 14:14:47 +08:00
shijingjing
bf6d86bf4e 媒资类型 2022-06-13 13:59:03 +08:00
aixianling
95ac3d55ae Merge remote-tracking branch 'origin/dev' into dev 2022-06-13 13:50:28 +08:00
aixianling
733e873785 BUG 30174 2022-06-13 13:50:11 +08:00
shijingjing
a0b90c4299 30165 2022-06-13 13:42:19 +08:00
shijingjing
3ab05fc552 v-show 2022-06-13 11:25:35 +08:00
shijingjing
1c44c9e776 监听 2022-06-13 11:13:36 +08:00
shijingjing
f34a0ac163 taskType 2022-06-13 11:03:44 +08:00
aixianling
570256341d 优化开发展示 2022-06-13 10:51:55 +08:00
aixianling
6e8b6b41df 优化开发展示 2022-06-13 10:49:25 +08:00
aixianling
94ee820ace 优化开发展示 2022-06-13 10:48:23 +08:00
aixianling
3080718d95 Merge remote-tracking branch 'origin/dev' into dev 2022-06-13 10:47:09 +08:00
aixianling
b35314bf83 优化开发展示 2022-06-13 10:46:55 +08:00
shijingjing
1dbe9c1a2b bug 2022-06-13 10:44:58 +08:00
shijingjing
241395d610 30164 2022-06-13 10:34:12 +08:00
shijingjing
2062bc6160 撤回 2022-06-13 10:30:16 +08:00
shijingjing
41687a386b 30163 2022-06-13 10:26:14 +08:00
shijingjing
c1c046971e 30159 2022-06-13 10:20:34 +08:00
shijingjing
b25222b93e 30161 2022-06-13 10:04:01 +08:00
shijingjing
ea85e1c82b 30155 2022-06-13 09:56:13 +08:00
shijingjing
8fe7970b81 30156 2022-06-13 09:40:10 +08:00
aixianling
2a4d9b2b1c 无等级网格版合并 2022-06-13 09:39:19 +08:00
shijingjing
0736ea98d0 30151 2022-06-13 09:09:45 +08:00
shijingjing
81a61c4ec4 防返贫 2022-06-11 15:45:50 +08:00
shijingjing
c5d3b941dc 防返贫 2022-06-11 15:08:40 +08:00
shijingjing
9a2623232c 撤回 2022-06-11 14:42:04 +08:00
shijingjing
96f565bbe4 播发记录 2022-06-11 14:36:19 +08:00
shijingjing
231717f862 任务列表 2022-06-11 13:16:21 +08:00
shijingjing
ca02cfc24e 大喇叭播放 2022-06-11 12:21:07 +08:00
aixianling
8e94580b56 山东移动版本追加 招工就业 2022-06-10 18:56:03 +08:00
shijingjing
3fdc528ffe 加载效果 2022-06-10 17:52:23 +08:00
liuye
35de4f51de Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-06-10 15:29:59 +08:00
liuye
3e5427633a 极光推送 2022-06-10 15:29:09 +08:00
aixianling
05ff4c5a0e Merge remote-tracking branch 'origin/dev' into dev 2022-06-10 15:24:36 +08:00
aixianling
ff8491c0f3 BUG 30148 2022-06-10 15:24:21 +08:00
liuye
fbb77ace5d 日期 2022-06-10 11:41:28 +08:00
liuye
438a24101d 分类查询 2022-06-10 11:18:19 +08:00
liuye
e6fe7b224b 极光推送 2022-06-10 11:09:16 +08:00
liuye
a407d007be 极光推送 2022-06-10 11:07:21 +08:00
shijingjing
d4534c7dca 设备 2022-06-10 10:06:55 +08:00
shijingjing
2b3925abf0 播发记录详情 2022-06-10 09:37:47 +08:00
aixianling
1fb21fdbd3 BUG 30099 2022-06-09 16:51:17 +08:00
shijingjing
0a49f98892 task 2022-06-09 16:42:46 +08:00
aixianling
a4348368e0 BUG 30139 2022-06-09 16:30:52 +08:00
aixianling
0dfe3125c7 BUG 30129 2022-06-09 16:24:21 +08:00
aixianling
c924ed7c71 BUG 30139 2022-06-09 16:23:05 +08:00
aixianling
ccb99b00c1 BUG 30132 2022-06-09 14:40:51 +08:00
shijingjing
c67633eda5 设备 2022-06-09 10:19:06 +08:00
shijingjing
55a7cd8624 选择设备 2022-06-09 08:39:26 +08:00
aixianling
b2600d0de5 BUG 29336 2022-06-08 19:23:25 +08:00
aixianling
f550ae832b Merge remote-tracking branch 'origin/dev' into dev 2022-06-08 19:20:21 +08:00
aixianling
6d338b8324 BUG 30066 2022-06-08 19:20:02 +08:00
shijingjing
92645d9c17 内容 2022-06-08 18:52:07 +08:00
aixianling
6d75362672 修复引入错误 2022-06-08 18:23:27 +08:00
aixianling
d5ecc2579b Merge remote-tracking branch 'origin/dev' into dev 2022-06-08 18:02:45 +08:00
aixianling
6dab0e1f72 BUG 30117 2022-06-08 18:02:08 +08:00
shijingjing
d24898b558 任务详情 2022-06-08 17:57:19 +08:00
shijingjing
fc220c7868 任务列表 2022-06-08 17:19:32 +08:00
shijingjing
33294ac8e7 详情 2022-06-08 16:51:45 +08:00
aixianling
07ca7dc8a7 埋点调整 2022-06-08 16:32:01 +08:00
aixianling
3365fcb1ef 迁移一个代码生成 2022-06-08 15:44:13 +08:00
aixianling
fa7c5428c5 BUG 30095 2022-06-08 10:19:42 +08:00
aixianling
c9dc8940ed BUG 30094 2022-06-08 10:06:18 +08:00
aixianling
e20e479697 BUG 30065 2022-06-08 09:29:15 +08:00
aixianling
c752a1c92b BUG 30069 2022-06-08 09:28:11 +08:00
aixianling
05af474916 随手拍 2022-06-07 18:23:10 +08:00
aixianling
b4e54b8fdc 异常值处理 2022-06-07 17:55:01 +08:00
aixianling
0b89f4c0a1 BUG 30044 2022-06-07 17:46:19 +08:00
aixianling
70e1337980 BUG 30043 2022-06-07 17:37:49 +08:00
aixianling
4b04209e62 BUG 30031 2022-06-07 17:04:38 +08:00
aixianling
0d31afa0a5 BUG 30045 2022-06-07 16:56:37 +08:00
aixianling
893ec0efc9 BUG 30045 2022-06-07 16:46:14 +08:00
aixianling
47d44a94b8 BUG 30018 2022-06-07 16:34:09 +08:00
aixianling
a1ee74f4c8 换个毛玻璃试试看 2022-06-07 14:49:04 +08:00
aixianling
61bacc2742 BUG 30021 2022-06-07 14:04:06 +08:00
aixianling
6c581378e8 BUG 30022 2022-06-07 11:34:05 +08:00
aixianling
d819783b21 增加beta测试开发环境和包环境 2022-06-06 16:02:33 +08:00
aixianling
a0cf4601b7 BUG 29998 2022-06-06 13:59:52 +08:00
aixianling
3a39248f9c BUG 29992 2022-06-06 11:36:12 +08:00
aixianling
f8f4c2ffec BUG 30004 2022-06-06 11:30:04 +08:00
aixianling
94331d6ba0 BUG 30003 2022-06-06 11:22:15 +08:00
aixianling
34dd2fcbcc Merge remote-tracking branch 'origin/dev' into dev 2022-06-06 10:49:58 +08:00
aixianling
53d0350259 增加corpId显示 2022-06-06 10:49:39 +08:00
yanran200730
d510da6e71 大屏 2022-06-06 10:43:28 +08:00
aixianling
eda3252c95 评论调整 2022-06-06 09:16:39 +08:00
liuye
c353a19fe5 30006 2022-06-02 18:03:13 +08:00
liuye
15877d15f4 积分 2022-06-02 17:54:06 +08:00
yanran200730
8ee4054eff Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-06-02 09:58:49 +08:00
yanran200730
94e27be64b 素材 支持视频 2022-06-02 09:58:41 +08:00
liuye
10e658af76 员工积分 2022-06-02 09:47:42 +08:00
aixianling
c93c5b6c93 小程序发布展示更多的信息和匹配更多的查询 2022-06-01 11:06:48 +08:00
aixianling
b7dfd189a0 山东迁移积分申请到标准版 2022-06-01 10:13:00 +08:00
aixianling
58c3d89297 网格调整完毕 2022-06-01 10:10:34 +08:00
aixianling
49aa0a6276 网格基础设置调整 2022-06-01 09:57:15 +08:00
aixianling
e71d1fcf12 网格区块基本调整完毕 2022-05-31 18:33:43 +08:00
aixianling
a09048af63 BUG 29970 2022-05-31 16:51:23 +08:00
aixianling
f446104dda 调整部分框架 2022-05-30 18:46:47 +08:00
aixianling
c17018ae9d BUG 29777 2022-05-30 15:07:25 +08:00
aixianling
69509c43f1 添加山东移动构建发布 2022-05-27 18:14:43 +08:00
aixianling
8a25040a26 优化打包交互 2022-05-27 15:19:16 +08:00
aixianling
aaf7631ef3 增加web端产品库模块,并增加埋点 2022-05-27 15:13:14 +08:00
aixianling
a134902bd6 BUG 29893 2022-05-27 13:59:27 +08:00
aixianling
768c0759ac BUG 29882 2022-05-27 13:52:48 +08:00
aixianling
442296a414 优化打包 2022-05-27 12:05:46 +08:00
aixianling
90ab577eb1 排除grid进行打包 2022-05-27 12:03:00 +08:00
aixianling
bf799bdd93 小程序发布跟新 2022-05-27 11:58:51 +08:00
aixianling
0debe23873 新网格应用调整目录完成 2022-05-27 11:51:18 +08:00
aixianling
79e06e38ae 优化打包交互 2022-05-27 10:10:04 +08:00
aixianling
d94fdb9f86 优化打包查询服务 2022-05-27 09:12:29 +08:00
aixianling
6d35edee98 更新部署打包服务 2022-05-26 19:00:53 +08:00
aixianling
45cde1e2e7 BUG 29874 2022-05-26 17:23:12 +08:00
liuye
b63cd4b427 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-05-26 16:17:53 +08:00
liuye
97d5c51a12 屏蔽积分类型 2022-05-26 16:17:36 +08:00
aixianling
1ea7bf16f2 山东移动追加应用积分维护和员工积分 2022-05-26 09:25:15 +08:00
aixianling
3a7506e0f6 BUG 29875 2022-05-26 08:57:44 +08:00
aixianling
09bc287157 BUG 29874 2022-05-26 08:53:46 +08:00
aixianling
99555c3924 Merge remote-tracking branch 'origin/dev' into dev 2022-05-25 18:50:03 +08:00
aixianling
82d93a1266 BUG 29869 2022-05-25 18:49:44 +08:00
liuye
0913a70ac7 导出 2022-05-25 18:11:36 +08:00
liuye
75d1f34b5d 禅道bug 2022-05-25 16:19:22 +08:00
aixianling
8424a06217 消除警告 2022-05-25 13:39:30 +08:00
aixianling
67d3ad9bca 增加是否可评论 2022-05-25 11:55:34 +08:00
aixianling
bcef93975e 修复核心库发布功能 2022-05-25 09:42:18 +08:00
aixianling
cf6610153f 秀山金融大屏完成 2022-05-23 21:04:48 +08:00
aixianling
e46dc98f58 url参数控制请求的代理指向 2022-05-23 15:03:57 +08:00
aixianling
261a6c6ffa Merge remote-tracking branch 'origin/dev' into dev 2022-05-23 14:42:49 +08:00
aixianling
4eb47552b3 BUG 29775 2022-05-23 14:42:25 +08:00
liuye
a4ac8060ba 29753 2022-05-23 11:40:27 +08:00
aixianling
4d99866e39 BUG 29657 2022-05-23 10:36:10 +08:00
aixianling
f6d36a132d BUG 29681 2022-05-23 10:32:09 +08:00
aixianling
97c43de5ce BUG 29681 2022-05-23 10:31:19 +08:00
aixianling
4bcf08213f BUG 29751 2022-05-23 10:09:04 +08:00
aixianling
1643123b77 BUG 29733 2022-05-23 09:16:41 +08:00
aixianling
48a6abc8b0 BUG 29766 2022-05-23 09:13:53 +08:00
aixianling
ffcd58a34a BUG 29657 2022-05-20 17:28:32 +08:00
aixianling
7eb409548b BUG 29672 2022-05-20 17:25:56 +08:00
aixianling
81701253cd BUG 29675 2022-05-20 17:22:39 +08:00
aixianling
89bcc1c27b BUG 29677 2022-05-20 17:16:30 +08:00
aixianling
f39003c785 BUG 29678 2022-05-20 17:15:29 +08:00
aixianling
a2c7c4628d BUG 29668 2022-05-20 17:13:04 +08:00
aixianling
7b2a394d9c BUG 29680 2022-05-20 17:11:54 +08:00
aixianling
5916681635 BUG 29716 2022-05-20 17:10:30 +08:00
aixianling
b578e07243 BUG 29751 2022-05-20 16:45:38 +08:00
aixianling
a73749b450 BUG 29681 2022-05-20 16:40:34 +08:00
aixianling
c27a19a06b BUG 29700 2022-05-20 15:43:28 +08:00
aixianling
234b9f34d5 BUG 29733 2022-05-20 15:41:38 +08:00
aixianling
93f1523caa Merge remote-tracking branch 'origin/dev' into dev 2022-05-20 15:39:35 +08:00
aixianling
b22c153f3d BUG 29744 2022-05-20 15:39:12 +08:00
liuye
2a416e8177 29743 2022-05-20 15:33:27 +08:00
aixianling
3bca9a4865 清理复制代码 2022-05-20 15:28:56 +08:00
liuye
b0457b8161 帮扶申报 2022-05-20 13:55:42 +08:00
liuye
16aaa2e95a 29709 2022-05-20 11:59:04 +08:00
liuye
be0c55de75 帮扶申报 2022-05-20 11:53:51 +08:00
aixianling
e0d1860aaa 增加企微应用产品库台账 2022-05-20 09:34:06 +08:00
aixianling
a73d93c1ca 增设埋点 2022-05-20 09:28:55 +08:00
aixianling
9ce09b38de BUG 29657 2022-05-19 18:33:38 +08:00
aixianling
ad856bfaae BUG 29658 2022-05-19 18:32:33 +08:00
aixianling
f17b80abba BUG 29659 2022-05-19 18:31:24 +08:00
aixianling
9b36b9de6d BUG 29661 2022-05-19 18:29:55 +08:00
aixianling
479163c50e BUG 29663 2022-05-19 18:12:52 +08:00
aixianling
305345a955 BUG 29662 2022-05-19 18:05:30 +08:00
aixianling
4414bd3416 BUG 29664 2022-05-19 18:03:01 +08:00
aixianling
c5d1030940 BUG 29666 2022-05-19 18:01:14 +08:00
aixianling
b0ea8c451b BUG 29667 2022-05-19 17:58:29 +08:00
aixianling
61217e07b8 BUG 29673 2022-05-19 17:52:51 +08:00
aixianling
79efa10aa1 完善正则式 2022-05-19 17:35:08 +08:00
liuye
63286e3f48 帮扶申报 2022-05-19 15:33:51 +08:00
liuye
5f853d5ac3 29576 2022-05-19 14:16:53 +08:00
liuye
6abe23d791 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-05-19 11:44:31 +08:00
liuye
4e36387bb2 帮扶申报 2022-05-19 11:43:39 +08:00
aixianling
fd03bba979 去掉新增 2022-05-19 11:00:43 +08:00
aixianling
a084961c0b 小程序产品库台账 2022-05-19 10:43:21 +08:00
aixianling
150760f6ce 小程序发布完成 2022-05-18 18:44:56 +08:00
aixianling
59931236ba BUG 29649 2022-05-18 14:21:47 +08:00
liuye
fd5f976dcf 29586 2022-05-18 11:47:31 +08:00
liuye
932733839f Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-05-18 11:38:51 +08:00
liuye
4fc53f7519 28305 2022-05-18 11:38:25 +08:00
aixianling
f71e163e0a Merge remote-tracking branch 'origin/dev' into dev 2022-05-18 11:34:30 +08:00
aixianling
18c7277d7b 标签信息增加权限码控制 2022-05-18 11:34:13 +08:00
liuye
829e2f5ab8 29576 2022-05-18 11:31:48 +08:00
liuye
79c6636fb2 话术库bug 2022-05-18 10:02:15 +08:00
liuye
5403db62fa 居民档案bug 2022-05-18 09:40:28 +08:00
liuye
425db08622 党员添加 2022-05-17 16:03:43 +08:00
liuye
0e7f0b4d26 29642 2022-05-17 15:47:43 +08:00
aixianling
697b0a5eaf 排查故障 2022-05-17 15:05:20 +08:00
aixianling
364f042e9b 员工积分完成 2022-05-17 14:27:32 +08:00
aixianling
da259ebec6 修复一下tab页签 2022-05-17 10:54:34 +08:00
aixianling
dbca23bb6d 增加积分规则表单验证 2022-05-16 17:55:51 +08:00
aixianling
64eafa988b 积分规则调整完毕 2022-05-16 17:44:21 +08:00
aixianling
355a0fe50e 党员积分导入按钮 2022-05-16 16:35:50 +08:00
aixianling
46c5474b4e 党员积分导入按钮 2022-05-16 16:35:41 +08:00
aixianling
23d677bc82 调整接口工具类 2022-05-16 11:10:11 +08:00
aixianling
5eaf8f996a 保存历史操作 2022-05-16 10:53:21 +08:00
shijingjing
733871805a 字典 2022-05-16 09:21:11 +08:00
shijingjing
86dbce3da8 29126 2022-05-16 09:03:16 +08:00
aixianling
d4ab166fe0 Merge remote-tracking branch 'origin/dev' into dev 2022-05-13 18:10:55 +08:00
aixianling
0705687d12 积分规则调整 2022-05-13 18:10:34 +08:00
yanran200730
246aaee5b1 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-05-13 18:02:46 +08:00
yanran200730
ca4a465312 大华大屏 2022-05-13 18:02:38 +08:00
aixianling
e4ce3d7c45 Merge remote-tracking branch 'origin/dev' into dev 2022-05-13 17:50:05 +08:00
aixianling
b90cc9065f BUG 29587 2022-05-13 17:49:45 +08:00
yanran200730
69ea4af045 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-05-13 17:33:53 +08:00
yanran200730
7e89712bd9 大华监控视频组件 2022-05-13 17:33:45 +08:00
aixianling
dfa29e1677 积分整合 2022-05-13 17:29:46 +08:00
aixianling
aef1ebc8c9 积分整合 2022-05-13 17:06:55 +08:00
aixianling
5d656a9e65 积分整合 2022-05-13 16:14:55 +08:00
yanran200730
e04acbcf5b Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-05-13 14:55:21 +08:00
yanran200730
1f7e2b4d84 党建大屏 2022-05-13 14:55:13 +08:00
aixianling
d6d2e7b909 BUG 29578 2022-05-12 18:42:30 +08:00
aixianling
7de09aa195 BUG 29580 2022-05-12 18:28:58 +08:00
aixianling
6835f1da50 BUG 29587 2022-05-12 18:26:57 +08:00
aixianling
2004368c90 BUG 29594 2022-05-12 18:14:24 +08:00
aixianling
ec41626868 整合积分integralDetailBizType 2022-05-12 16:25:22 +08:00
aixianling
d1acd1de71 Merge remote-tracking branch 'origin/dev' into dev 2022-05-12 16:22:50 +08:00
aixianling
f6d8a737df 整合积分等报错 2022-05-12 16:22:31 +08:00
yanran200730
37e16f5795 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-05-12 15:25:46 +08:00
yanran200730
d5d5fa6055 党建大屏 2022-05-12 15:25:35 +08:00
shijingjing
6ec577f14d 29128 2022-05-12 15:22:38 +08:00
liuye
9300dac087 融资统计 2022-05-12 14:53:59 +08:00
liuye
3f25e3a753 29132 2022-05-12 14:42:44 +08:00
shijingjing
5dc1ba2230 29128 2022-05-12 10:53:05 +08:00
shijingjing
208b440c86 29165 2022-05-12 10:30:04 +08:00
shijingjing
8bc6655ec7 改一下 2022-05-12 09:49:25 +08:00
shijingjing
d2bec8554d 29592 2022-05-12 09:43:20 +08:00
yanran200730
7453962f52 党建大屏 2022-05-11 18:07:04 +08:00
yanran200730
4b518445ef Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-05-11 16:47:22 +08:00
yanran200730
f9d5e51222 大屏 环形图组件 2022-05-11 16:47:15 +08:00
aixianling
5b94b47e02 Merge remote-tracking branch 'origin/dev' into dev 2022-05-11 14:26:35 +08:00
aixianling
1464cfa2de 修复node和esm兼容问题 2022-05-11 14:24:24 +08:00
yanran200730
e4d1e85156 echart 组件 2022-05-11 11:37:44 +08:00
yanran200730
8998e9a664 bug 2022-05-11 10:20:59 +08:00
yanran200730
97d29d0d7e Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-05-11 09:47:29 +08:00
yanran200730
a4d48f643b 新增饼图组件 2022-05-11 09:47:09 +08:00
shijingjing
5d4a8af8d7 28735 28741 2022-05-11 09:33:32 +08:00
aixianling
0f221d2f9d 目录代码整合 2022-05-11 08:54:06 +08:00
aixianling
322d0cb479 目录代码整合 2022-05-10 20:18:12 +08:00
aixianling
e91d1f73dc Merge branch 'dev' into vite
# Conflicts:
#	examples/App.vue
#	examples/router/autoRoutes.js
#	examples/utils/index.js
#	package.json
#	packages/wechat/AppProjectActivities/components/Event.vue
#	project/dv/apps/AppHomesteadDV.vue
#	vue.config.js
2022-05-10 20:06:15 +08:00
aixianling
036ee91533 目录代码整合 2022-05-10 20:02:37 +08:00
aixianling
71049f7f65 调整界面和底座风格基本保持一致 2022-05-10 19:16:02 +08:00
aixianling
f39746e303 调整界面和底座风格基本保持一致 2022-05-10 18:46:57 +08:00
aixianling
c0d890a0a8 优化一下产品库加载 2022-05-10 16:54:21 +08:00
aixianling
d0e18eb2f6 提交一下 2022-05-10 15:11:52 +08:00
aixianling
82535aff40 3.0第一个产品库 2022-05-10 14:43:49 +08:00
aixianling
65fb4ac65b 修复favicon 2022-05-10 11:35:25 +08:00
aixianling
93d0e0aafe 修复刷新异常 2022-05-10 11:27:19 +08:00
aixianling
1eb9c532f3 Merge branch 'dev' into vite 2022-05-10 11:15:51 +08:00
liuye
b4446a24a6 运营平台bug 2022-05-10 11:02:57 +08:00
aixianling
3174382666 Merge branch 'dev' into vite 2022-05-10 09:56:50 +08:00
aixianling
e8c8c1cba6 BUG 29560 2022-05-10 09:56:08 +08:00
aixianling
92890111ee BUG 29560 2022-05-10 09:36:35 +08:00
aixianling
9b35506181 Merge branch 'dev' into vite 2022-05-10 09:21:34 +08:00
aixianling
73f300cd7a 先提交一波 2022-05-10 09:21:07 +08:00
yanran200730
3dd57db73b Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-05-09 16:07:17 +08:00
yanran200730
a2925da21b 网格bug 2022-05-09 16:07:07 +08:00
aixianling
2f79210970 Merge branch 'dev' into vite
# Conflicts:
#	package.json
#	packages/bigscreen/designer/AppDesigner.vue
#	packages/bigscreen/designer/components/Add.vue
#	packages/bigscreen/designer/components/Layout.vue
#	packages/bigscreen/designer/components/RenderElement.vue
#	packages/bigscreen/viewer/AppGigscreenViewer.vue
#	project/dvui/layout/AiDvPanel/AiDvPanel.vue
#	project/dvui/layout/AiDvWrapper/AiDvWrapper.vue
2022-05-09 14:36:16 +08:00
aixianling
c3d92c18d0 Merge remote-tracking branch 'origin/dev' into dev 2022-05-09 14:33:01 +08:00
aixianling
ae24b4d6b4 BUG 29559 2022-05-09 14:32:42 +08:00
liuye
61de1da32d 29553 2022-05-09 08:43:37 +08:00
aixianling
70557adefd 地图标绘调整 2022-05-07 19:31:07 +08:00
aixianling
7894fb68f8 Merge remote-tracking branch 'origin/dev' into dev 2022-05-07 18:14:56 +08:00
aixianling
409fcd6f44 标绘重新调整 2022-05-07 18:14:37 +08:00
yanran200730
61fed1f99f bug 2022-05-07 15:58:00 +08:00
yanran200730
32aae8fe4f 29536 2022-05-07 09:17:23 +08:00
yanran200730
74e34e52e8 2 2022-05-06 20:10:09 +08:00
yanran200730
4b9bd8ffa8 bug 2022-05-06 19:55:29 +08:00
yanran200730
018b926c6c bug 2022-05-06 19:54:02 +08:00
yanran200730
1355ef7509 29511 2022-05-06 19:20:36 +08:00
yanran200730
a076c7b331 29513 2022-05-06 19:08:34 +08:00
yanran200730
195c6e3aa6 29512 2022-05-06 19:06:42 +08:00
yanran200730
046b1d0c5a bug 2022-05-06 18:54:19 +08:00
yanran200730
b6a686a021 bug 2022-05-06 18:53:49 +08:00
yanran200730
bc8cc63d17 bug 2022-05-06 18:47:16 +08:00
yanran200730
db406eb8fa 29519 2022-05-06 17:49:34 +08:00
yanran200730
c1010119aa 29520 2022-05-06 17:47:43 +08:00
yanran200730
a0cc85027c 29522 2022-05-06 17:36:13 +08:00
yanran200730
1db79c53a0 党建大屏 2022-05-06 16:31:28 +08:00
yanran200730
39f6cb1ff2 党建大屏 2022-05-06 16:26:11 +08:00
aixianling
55e3ab0612 BUG 29505 2022-05-05 18:22:27 +08:00
yanran200730
84954bcc84 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-05-05 18:00:31 +08:00
yanran200730
a0c2bf8f67 党建大屏 2022-05-05 18:00:21 +08:00
aixianling
bd2b066e9a BUG 29508 2022-05-05 16:45:19 +08:00
aixianling
7d99c2fb5f BUG 29505 2022-05-05 16:25:17 +08:00
aixianling
6d3984654c BUG 29503 2022-05-05 16:21:13 +08:00
aixianling
64202161dd BUG 29507 2022-05-05 16:02:58 +08:00
yanran200730
6f14126a2e Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-05-05 15:29:02 +08:00
yanran200730
f757852ac4 大屏组件 2022-05-05 15:28:56 +08:00
aixianling
f38eff6564 BUG 29501 2022-05-05 15:26:44 +08:00
aixianling
92516a7753 优化打包脚本 2022-05-05 15:16:28 +08:00
aixianling
890cbaa0b9 BUG 29468 2022-04-29 19:47:51 +08:00
aixianling
376a4778b8 BUG 29467 2022-04-29 19:39:17 +08:00
aixianling
cc46a5a9c8 BUG 29441 2022-04-29 17:53:10 +08:00
aixianling
e8439fe40a BUG 29454 2022-04-29 16:47:21 +08:00
aixianling
3464798fd9 BUG 29452 2022-04-29 16:44:14 +08:00
aixianling
5a730afb99 BUG 29451 2022-04-29 16:42:40 +08:00
aixianling
46596b6d57 BUG 29451 2022-04-29 16:42:26 +08:00
aixianling
8a0141bf2d BUG 29450 2022-04-29 16:39:37 +08:00
aixianling
869d9a4635 BUG 29446 2022-04-29 16:24:13 +08:00
aixianling
6eb9dd2ee6 BUG 29441 2022-04-29 16:13:28 +08:00
aixianling
47024dde2a BUG 29439 2022-04-29 16:11:09 +08:00
aixianling
f764b37c8a BUG 29436 2022-04-29 16:08:43 +08:00
aixianling
85324959a0 BUG 29420 2022-04-29 16:04:32 +08:00
aixianling
6298eeaae3 BUG 29306 2022-04-29 15:53:42 +08:00
aixianling
c398a354b9 BUG 29286 2022-04-29 15:44:01 +08:00
aixianling
abe2f9892e 合并网格管理员并权限控制 2022-04-29 14:32:08 +08:00
aixianling
8744f115cf Merge branch 'dev' into vite
# Conflicts:
#	packages/IntelligentSecurity/AppISManage/AppISManage.vue
#	vue.config.js
2022-04-28 18:42:05 +08:00
aixianling
cf4ae0bc58 Merge remote-tracking branch 'origin/dev' into dev 2022-04-28 18:40:10 +08:00
aixianling
4cb734cbe0 网格管理调整完毕 2022-04-28 18:39:32 +08:00
liuye
a4e7a9ff30 29412 2022-04-28 18:08:34 +08:00
liuye
572f155bf5 29411 2022-04-28 17:39:07 +08:00
liuye
99ef026ff0 bug 2022-04-28 17:23:10 +08:00
aixianling
86a1128d9a Merge remote-tracking branch 'origin/dev' into dev 2022-04-28 16:25:47 +08:00
aixianling
38f3ecc288 saas研发配置及网格调整 2022-04-28 16:25:30 +08:00
liuye
ec29f1dc11 29370 2022-04-28 15:41:43 +08:00
yanran200730
c186b95ae7 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-04-28 15:18:53 +08:00
yanran200730
d5fa92d90f bug 2022-04-28 15:18:36 +08:00
aixianling
6f5a918bd1 BUG 29401 2022-04-28 15:16:32 +08:00
aixianling
96ad4ac999 Merge remote-tracking branch 'origin/dev' into dev 2022-04-28 15:01:07 +08:00
aixianling
efc3252c1b BUG 29400 2022-04-28 15:00:51 +08:00
liuye
197201d923 29399 2022-04-28 14:49:04 +08:00
liuye
8baf806758 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-04-28 14:32:43 +08:00
liuye
192af31223 风险消除 收入情况 2022-04-28 14:32:15 +08:00
aixianling
dc2e2ff079 Merge remote-tracking branch 'origin/dev' into dev 2022-04-28 14:30:42 +08:00
aixianling
97759ee9d2 调整一下名字 2022-04-28 14:30:20 +08:00
yanran200730
ea42e0e53a 29391 2022-04-28 14:26:46 +08:00
yanran200730
b85a5a9cfb Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-04-28 14:02:08 +08:00
yanran200730
001fc94d95 29392 2022-04-28 14:02:01 +08:00
liuye
5f8fff9943 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-04-28 11:50:55 +08:00
liuye
476dec8d17 去掉备注说明 2022-04-28 11:50:35 +08:00
aixianling
0a815cbb35 调整一下名字 2022-04-28 11:49:23 +08:00
liuye
74b98805a5 脱贫年度 2022-04-28 11:35:48 +08:00
liuye
b5d7ee5c58 bug 2022-04-28 11:21:28 +08:00
yanran200730
d970a443ce 29266 2022-04-28 10:50:39 +08:00
yanran200730
22cbb0c6bf 29369 2022-04-28 10:30:53 +08:00
yanran200730
a23dc0b0cd Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-04-28 10:28:24 +08:00
yanran200730
7bbeb88804 bug 2022-04-28 10:28:18 +08:00
aixianling
27f9d4740d BUG 29277 2022-04-28 10:08:46 +08:00
aixianling
c0c5cd79ee Merge remote-tracking branch 'origin/dev' into dev 2022-04-28 10:00:28 +08:00
aixianling
a6c9430a42 BUG 29300 2022-04-28 10:00:09 +08:00
liuye
b468befe67 29379 2022-04-28 09:55:30 +08:00
aixianling
b6bcf204f5 Merge remote-tracking branch 'origin/dev' into dev 2022-04-28 09:41:36 +08:00
aixianling
7bc5f87471 BUG 29286 2022-04-28 09:41:21 +08:00
liuye
bb46e123fe bug 2022-04-28 09:28:18 +08:00
yanran200730
e99ea5b2de Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-04-28 09:27:17 +08:00
yanran200730
40dfa8686b 视频回放bug 2022-04-28 09:27:12 +08:00
aixianling
731389d4a2 BUG 29112 2022-04-28 09:03:18 +08:00
aixianling
2174909bb8 Merge remote-tracking branch 'origin/dev' into vite 2022-04-28 08:56:10 +08:00
aixianling
bd512c3caa 优化体验 2022-04-27 19:36:32 +08:00
liuye
7c13051ce1 格式化 2022-04-27 18:34:00 +08:00
liuye
bfde95f6ca 监测对象 2022-04-27 18:32:22 +08:00
liuye
9861b4718e bug 2022-04-27 18:24:03 +08:00
aixianling
861e7c688f Merge branch 'dev' into vite 2022-04-27 18:20:28 +08:00
aixianling
4f0178c627 web端产品库 vite版本 2022-04-27 18:18:57 +08:00
liuye
2f612a074c 监测对象字段 2022-04-27 18:08:01 +08:00
liuye
11eda3d90b 监测对象字段 2022-04-27 17:53:58 +08:00
liuye
c78a75718a 监测对象 2022-04-27 09:48:09 +08:00
aixianling
ee93320cad Merge remote-tracking branch 'origin/dev' into dev 2022-04-27 08:59:20 +08:00
aixianling
35fcde4dca BUG 29252 2022-04-27 08:59:01 +08:00
liuye
054f8b8a50 监测对象列表删除按钮 2022-04-26 17:48:26 +08:00
liuye
8f79d72950 29305 2022-04-26 17:26:13 +08:00
liuye
3ba4c9089c 29289 2022-04-26 17:16:37 +08:00
liuye
471609f59c 监测对象 2022-04-26 16:43:48 +08:00
liuye
ffcd6f2943 宣传资讯列表 2022-04-26 16:11:03 +08:00
liuye
abdeeef32f 标题居左 2022-04-26 16:04:04 +08:00
liuye
fa64373189 宣传资讯 2022-04-26 15:57:14 +08:00
liuye
10cb930034 宣传资讯 2022-04-26 15:52:03 +08:00
liuye
ab3e8ad93f 权限 2022-04-26 15:14:46 +08:00
liuye
a45e5a8844 网格员id 2022-04-26 14:53:21 +08:00
liuye
91f8c77e34 回撤 2022-04-26 14:33:47 +08:00
liuye
98a228e644 审核状态 2022-04-26 14:30:16 +08:00
liuye
bc9a255a3f 29290 2022-04-26 14:15:12 +08:00
liuye
5c3e626df1 选择人员 2022-04-26 14:00:40 +08:00
liuye
4db2c45c4a bug 2022-04-26 13:44:36 +08:00
liuye
c921eec601 bug 2022-04-26 11:45:01 +08:00
liuye
ab146f9a69 bug 2022-04-26 11:36:59 +08:00
liuye
48b3839eca 29279 2022-04-26 11:18:30 +08:00
liuye
7e19978d7a 监测对象 2022-04-26 10:36:06 +08:00
liuye
050f76c1be 监测对象 2022-04-25 18:09:11 +08:00
f4873d924f BUG 29255 2022-04-25 15:58:51 +08:00
6fedce8dac Merge remote-tracking branch 'origin/dev' into dev 2022-04-25 15:55:31 +08:00
9f4c44d75d BUG 29162 2022-04-25 15:55:08 +08:00
liuye
f0e3aaa3ab bug 2022-04-25 15:39:32 +08:00
liuye
9521730bae 宣传资讯 2022-04-25 14:37:24 +08:00
liuye
ac99e83459 政策申办统计导入 2022-04-25 11:57:02 +08:00
liuye
3ce7f47a6b 政策申办 2022-04-25 10:49:34 +08:00
liuye
c430bbf467 政策申办统计 2022-04-25 10:30:08 +08:00
liuye
ea36a748c8 宣传资讯 2022-04-25 08:58:10 +08:00
2c5542d985 BUG 29263 2022-04-24 10:17:14 +08:00
722d861dfd Merge remote-tracking branch 'origin/dev' into dev 2022-04-24 10:12:27 +08:00
5ea1728dbb BUG 29268 2022-04-24 10:12:13 +08:00
yanran200730
53a4e5ea27 优化 2022-04-24 09:53:36 +08:00
6a75a3470f BUG 29264 2022-04-22 17:12:06 +08:00
8600eb20bc BUG 29263 2022-04-22 17:04:00 +08:00
yanran200730
2074d29e55 bug 2022-04-22 16:33:22 +08:00
yanran200730
9283c0c283 29259 2022-04-22 16:14:31 +08:00
yanran200730
b25f4ff713 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-04-22 16:09:19 +08:00
yanran200730
17c74dd956 29258 2022-04-22 16:09:09 +08:00
e0bb149e44 Merge remote-tracking branch 'origin/dev' into dev 2022-04-22 16:00:20 +08:00
f81e56feab BUG 29262 2022-04-22 16:00:07 +08:00
刘仕伟
4b994d76e9 修改三涧溪apps的引入 2022-04-22 07:54:53 +00:00
426ce5f49a Merge remote-tracking branch 'origin/dev' into dev 2022-04-22 15:45:07 +08:00
460a2b0ab7 BUG 29252 2022-04-22 15:44:55 +08:00
yanran200730
9c0685e4ff 29257 2022-04-22 15:44:04 +08:00
3abcf75a3f BUG 29255 2022-04-22 15:29:53 +08:00
01e1bc3d7a BUG 29245 2022-04-22 15:28:08 +08:00
4d1df90887 Merge remote-tracking branch 'origin/dev' into dev 2022-04-22 15:24:09 +08:00
e687a6b572 BUG 29253 2022-04-22 15:23:59 +08:00
yanran200730
53a185fec6 优化 2022-04-22 14:21:21 +08:00
yanran200730
74adde5a40 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-04-22 14:13:13 +08:00
yanran200730
03d990f8b5 优化 2022-04-22 14:13:07 +08:00
d52d2b352d BUG 29254 2022-04-22 10:57:44 +08:00
41bc5e8750 BUG 29253 2022-04-22 10:49:44 +08:00
f796fbc536 BUG 29249 2022-04-22 10:48:21 +08:00
c6a9856689 BUG 29247 2022-04-22 10:39:46 +08:00
6359ceecb3 BUG 29247 2022-04-22 10:38:14 +08:00
f2bcbffde4 BUG 29245 2022-04-22 10:36:58 +08:00
8bdc53d7ca BUG 29244 2022-04-22 10:34:33 +08:00
d697c5213f BUG 29243 2022-04-22 10:33:49 +08:00
b7104acd58 BUG 29242 2022-04-22 10:30:18 +08:00
b84d3bec66 BUG 29227 2022-04-22 10:29:21 +08:00
d2264c90d1 Merge remote-tracking branch 'origin/dev' into dev 2022-04-22 09:57:33 +08:00
1d0de7a9c5 BUG 29241 2022-04-22 09:57:16 +08:00
yanran200730
cce3c47466 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-04-21 16:11:56 +08:00
yanran200730
a01d79fe2f 视频监控 2022-04-21 16:11:49 +08:00
283fb8767d BUG 29229 2022-04-21 15:08:31 +08:00
9baf7fe2ef Merge remote-tracking branch 'origin/dev' into dev 2022-04-21 15:07:38 +08:00
4ff43d632e BUG 29236 2022-04-21 15:07:22 +08:00
yanran200730
49dabf912c 视频监控 2022-04-21 15:04:23 +08:00
2fe01ec7cf BUG 29223 2022-04-21 15:02:24 +08:00
7250ff3a45 BUG 29202 2022-04-21 14:53:36 +08:00
832be3f1ec BUG 29192 2022-04-21 14:52:55 +08:00
69347cde15 BUG 29186 2022-04-21 14:47:53 +08:00
f384b4c73d BUG 29174 2022-04-21 14:32:31 +08:00
刘仕伟
0c2b0c6733 三涧溪添加标签管理 2022-04-21 10:04:10 +08:00
aixianling
a49fb6016b 增加删除按钮 2022-04-20 18:15:33 +08:00
aixianling
0370ea61d9 BUG 29228 2022-04-20 18:09:00 +08:00
aixianling
25bdc08ede BUG 29226 2022-04-20 18:07:44 +08:00
aixianling
e2583c25f9 BUG 29225 2022-04-20 18:07:04 +08:00
aixianling
d01a7b58fa BUG 29227 2022-04-20 18:04:59 +08:00
aixianling
d3cb80666e BUG 29205 2022-04-20 18:03:38 +08:00
aixianling
a52c3a1eca BUG 29172 2022-04-20 17:58:19 +08:00
aixianling
38fcdfdb70 BUG 29193 2022-04-20 17:55:05 +08:00
aixianling
2360db1924 BUG 29190 2022-04-20 17:53:12 +08:00
aixianling
9baf96b0c2 BUG 29194 2022-04-20 17:51:47 +08:00
aixianling
44e8683cd5 BUG 29196 2022-04-20 17:50:18 +08:00
aixianling
9efa58ad49 BUG 29200 2022-04-20 17:47:59 +08:00
aixianling
71631bf2ca BUG 29221 2022-04-20 17:46:45 +08:00
aixianling
22e7c83a74 BUG 29222 2022-04-20 17:22:39 +08:00
aixianling
2a6563a6c1 BUG 29197 2022-04-20 17:19:49 +08:00
aixianling
fe15dcdad9 Merge remote-tracking branch 'origin/dev' into dev 2022-04-20 17:08:42 +08:00
aixianling
bff298f5c9 标签管理完成 2022-04-20 17:08:25 +08:00
yanran200730
53d7b3fc85 监控视频回放 2022-04-20 16:37:04 +08:00
aixianling
893a75c582 增加学习强国积分 2022-04-20 14:51:51 +08:00
aixianling
86c8722638 居民档案结构重组 2022-04-20 14:19:14 +08:00
aixianling
d1e3e69006 标签管理完成 2022-04-20 13:44:25 +08:00
aixianling
8719b9d851 BUG 29168 2022-04-20 09:33:43 +08:00
aixianling
7cc8b5be93 BUG 29162 2022-04-20 09:31:05 +08:00
aixianling
b095835e62 BUG 29169 2022-04-20 09:25:57 +08:00
aixianling
8cc46723f0 Merge remote-tracking branch 'origin/dev' into dev 2022-04-20 08:56:45 +08:00
aixianling
4f52add246 BUG 29169 2022-04-20 08:56:25 +08:00
yanran200730
867ab92be8 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-04-19 17:59:29 +08:00
yanran200730
e36ebca88c 视频回放 2022-04-19 17:59:23 +08:00
aixianling
e854868514 车辆信息和房屋信息完成 2022-04-19 17:59:14 +08:00
aixianling
4ec129a695 标签管理样式完成 2022-04-19 15:39:30 +08:00
aixianling
99e8432ea7 标签管理样式完成 2022-04-19 15:36:41 +08:00
aixianling
31b3e6c670 居民档案样式调整完成 2022-04-19 15:11:48 +08:00
aixianling
459485c83b 居民档案调整完成 2022-04-19 12:14:59 +08:00
aixianling
5a14c5373b 补充未加载字典 2022-04-19 10:00:51 +08:00
aixianling
0c25c114d0 解绑字典工具类和vuex的强绑定,字典类可单独使用 2022-04-19 09:48:30 +08:00
aixianling
23edcd62d9 优化动态选择项 2022-04-18 19:16:37 +08:00
aixianling
7db829566c 调整调用接口 2022-04-18 19:04:47 +08:00
aixianling
7feea057bc 四邻联动记录完成 2022-04-18 19:02:37 +08:00
aixianling
52da9be2fc BUG 29162 2022-04-18 18:22:07 +08:00
aixianling
fb33d84784 BUG 29146 2022-04-18 18:18:46 +08:00
aixianling
506e4d5dac 区分下应用 2022-04-18 17:57:22 +08:00
aixianling
b16b5d5e6c 接口对接完毕 2022-04-18 17:52:54 +08:00
aixianling
96c2a69872 Merge remote-tracking branch 'origin/dev' into dev 2022-04-18 17:46:16 +08:00
aixianling
9bcbb2c851 党员积分明细完成 2022-04-18 17:46:02 +08:00
yanran200730
d0b56ba0d1 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-04-18 17:36:44 +08:00
yanran200730
a72cbd4811 视频协同 2022-04-18 17:36:38 +08:00
aixianling
0c69a922a5 党员积分 列表完成 2022-04-18 16:36:09 +08:00
aixianling
285fc7aaa9 Merge remote-tracking branch 'origin/dev' into dev 2022-04-18 16:21:57 +08:00
aixianling
d04eb1a4a7 党员积分 界面完成 2022-04-18 16:21:15 +08:00
刘仕伟
00a1adaf82 Update AiSlwVideo.vue 2022-04-18 07:41:05 +00:00
aixianling
ec93e7cc0d 增加党员简介完成 2022-04-18 15:29:42 +08:00
aixianling
f4f23b4814 四邻设置开发完成 2022-04-18 15:20:35 +08:00
刘仕伟
8002d58294 Update AiSlwVideo.vue 2022-04-18 03:08:02 +00:00
aixianling
222789a438 BUG 29118 2022-04-18 09:54:31 +08:00
aixianling
6ede9e8871 BUG 29142 2022-04-18 09:53:11 +08:00
aixianling
178d254bf8 BUG 29156 2022-04-18 09:50:11 +08:00
aixianling
8f01e046e0 BUG 29148 2022-04-18 09:30:36 +08:00
aixianling
99a9433c92 优秀党员追加 2022-04-15 16:43:18 +08:00
aixianling
9ff75ba4b5 Merge remote-tracking branch 'origin/dev' into dev 2022-04-15 16:06:41 +08:00
aixianling
e90f40671d 四邻联动页面完成 2022-04-15 16:06:29 +08:00
yanran200730
6ee61ae682 视频回放 2022-04-15 16:01:23 +08:00
yanran200730
669b56c5f9 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-04-15 14:41:18 +08:00
yanran200730
f42f6a165d 视频回放 2022-04-15 14:41:12 +08:00
aixianling
586f3746ad 三涧溪村项目配置 2022-04-15 14:06:23 +08:00
aixianling
f134ee8f26 Merge remote-tracking branch 'origin/dev' into dev 2022-04-15 14:04:46 +08:00
aixianling
e036ae13aa 三涧溪村项目配置 2022-04-15 14:04:27 +08:00
yanran200730
3d27008b40 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-04-15 14:04:13 +08:00
yanran200730
2aa6092938 视频回放 2022-04-15 14:04:08 +08:00
shijingjing
3e036b221f 29123 2022-04-15 11:35:41 +08:00
shijingjing
2d2865213e 29122 2022-04-15 11:26:39 +08:00
aixianling
9497074b72 BUG 29125 2022-04-15 11:26:22 +08:00
aixianling
19a18e34a5 BUG 29121 2022-04-15 11:22:27 +08:00
aixianling
e72ffbf7d0 BUG 29119 2022-04-15 11:19:14 +08:00
aixianling
a0c547c510 BUG 29117 2022-04-15 11:16:20 +08:00
aixianling
761c93541b BUG 29115 2022-04-15 11:13:45 +08:00
aixianling
9d73267f8b 2.把贷款统计、融资统计中的交易记录,单独做个菜单(只要结果数据/放款和驳回) 2022-04-14 17:53:11 +08:00
aixianling
a6a38ef099 BUG 29105 2022-04-14 17:23:34 +08:00
aixianling
c997a099dc 2.申办业务时查看个人的报告信息(信息待定) 2022-04-14 17:21:18 +08:00
aixianling
46044e21fc 配置表单时所属部门字典改为非必填,选项中增加金融机构(富农贷是农行产品) 2022-04-14 14:58:50 +08:00
aixianling
04648a7ac6 BUG 29059 2022-04-14 14:53:37 +08:00
aixianling
babbb28d07 配置表单时所属部门字典改为非必填,选项中增加金融机构(富农贷是农行产品) 2022-04-14 14:47:42 +08:00
aixianling
64a98b4712 BUG 29102 2022-04-14 14:39:29 +08:00
aixianling
6291f35dca BUG 29108 2022-04-14 14:32:40 +08:00
aixianling
fcf81210fe BUG 29058 2022-04-14 14:29:24 +08:00
aixianling
89271cd829 配置表单时所属部门字典改为非必填,选项中增加金融机构(富农贷是农行产品) 2022-04-14 14:23:14 +08:00
aixianling
1f8810ad22 BUG 29073 2022-04-14 14:01:03 +08:00
aixianling
034961e472 BUG 29101 2022-04-14 13:57:02 +08:00
aixianling
831175383f BUG 29097 2022-04-14 11:41:47 +08:00
aixianling
17788948fd BUG 29104 2022-04-14 11:28:31 +08:00
aixianling
05a6149cd1 BUG 29103 2022-04-14 11:01:37 +08:00
aixianling
56c72397c1 BUG 29095 2022-04-14 09:41:50 +08:00
aixianling
48df62ac7b BUG 29093 2022-04-14 09:29:24 +08:00
aixianling
1da5d7aab5 Merge remote-tracking branch 'origin/dev' into dev 2022-04-14 09:29:12 +08:00
aixianling
143a3f1996 BUG 29093 2022-04-14 09:28:54 +08:00
yanran200730
9857d683cf Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-04-13 18:58:00 +08:00
yanran200730
a184ca666e 需求变更 2022-04-13 18:57:54 +08:00
aixianling
61b86011cc 信用积分多店铺改造 2022-04-13 18:31:07 +08:00
aixianling
fac5ed82bb 信用积分多店铺改造 2022-04-13 18:27:25 +08:00
aixianling
5e5d0b4308 新增机构时,需要选择LOGO范围 2022-04-13 18:09:37 +08:00
aixianling
67dab486e3 新增机构时,需要选择LOGO范围 2022-04-13 17:34:57 +08:00
aixianling
7ed3cc17a1 详情页咨询改为企业微信二维码 2022-04-13 17:30:55 +08:00
aixianling
d94bdc362d 详情页咨询改为企业微信二维码 2022-04-13 17:29:42 +08:00
aixianling
67ba57b994 详情页咨询改为企业微信二维码 2022-04-13 17:27:09 +08:00
aixianling
e326cf1f55 Merge remote-tracking branch 'origin/dev' into dev 2022-04-13 17:14:31 +08:00
aixianling
9410f2586a 产品已发布状态下也支持编辑,编辑提交后需再次审核 2022-04-13 17:13:32 +08:00
liuye
8a06fa7b2c 29083 2022-04-13 14:21:31 +08:00
shijingjing
d40905e60b 29069 2022-04-13 14:00:28 +08:00
shijingjing
5a850b066a 29038 2022-04-13 09:58:26 +08:00
shijingjing
dff04e7289 bug 2022-04-13 09:15:06 +08:00
shijingjing
a053a01777 bug 2022-04-13 09:13:30 +08:00
aixianling
c90615b313 Merge remote-tracking branch 'origin/dev' into dev 2022-04-13 09:01:45 +08:00
aixianling
8134ef2516 BUG 29070 2022-04-13 09:01:23 +08:00
shijingjing
b3b85f65fd bug 2022-04-12 18:12:45 +08:00
shijingjing
c71a44d7f1 29038 2022-04-12 17:53:01 +08:00
shijingjing
d671d5fc8b 29066 28996 2022-04-12 17:48:12 +08:00
aixianling
a6dfe82012 BUG 29032 2022-04-12 17:18:05 +08:00
aixianling
202ff931bd Merge remote-tracking branch 'origin/dev' into dev 2022-04-12 17:17:30 +08:00
aixianling
a8e6cb1710 BUG 29023 2022-04-12 17:17:10 +08:00
shijingjing
4e8670dcfa 29063 2022-04-12 17:16:55 +08:00
aixianling
8c3735fd6e Merge remote-tracking branch 'origin/dev' into dev 2022-04-12 16:01:38 +08:00
aixianling
f4f7963fff 山东移动监控应用=>标准版智能安防 2022-04-12 16:01:21 +08:00
liuye
6e5de10982 29026 2022-04-12 15:57:36 +08:00
liuye
427f890aa1 屏蔽放贷数量 2022-04-12 13:39:27 +08:00
aixianling
3607bc86e9 BUG 29059 2022-04-12 11:45:51 +08:00
aixianling
d7dc92ff4a BUG 29015 2022-04-12 11:44:26 +08:00
liuye
19453c366a 29060 2022-04-12 11:33:55 +08:00
aixianling
8779b59856 BUG 29051 2022-04-12 10:45:20 +08:00
aixianling
00afdc8f0a Merge remote-tracking branch 'origin/dev' into dev 2022-04-12 10:29:25 +08:00
aixianling
f84c90dbf7 BUG 29053 2022-04-12 10:28:22 +08:00
yanran200730
f06cc9b112 大屏复制功能 2022-04-12 10:13:24 +08:00
liuye
eb1f4a4a4e bug 2022-04-11 17:59:48 +08:00
liuye
72485b4ab9 bug 2022-04-11 16:15:30 +08:00
liuye
9f3b8d7416 29046 2022-04-11 16:11:47 +08:00
aixianling
a6f4458327 BUG 29045 2022-04-11 15:22:06 +08:00
aixianling
492a64ffb4 BUG 29043 2022-04-11 14:12:02 +08:00
aixianling
58bf9d0050 Merge remote-tracking branch 'origin/dev' into dev 2022-04-11 14:04:02 +08:00
aixianling
3dbf097447 BUG 28978 2022-04-11 14:03:42 +08:00
shijingjing
def72781e7 29042 2022-04-11 13:38:35 +08:00
liuye
ae749f9b25 29041 2022-04-11 11:53:16 +08:00
liuye
4a7a8b204f 查询机构列表 2022-04-11 11:30:50 +08:00
liuye
b29694352d 初始化数据 2022-04-11 11:28:20 +08:00
aixianling
15bdd4951d BUG 28859 2022-04-11 11:18:01 +08:00
aixianling
7b949beaac 统计地区筛选条件 2022-04-11 11:12:34 +08:00
aixianling
cf84815c54 Merge remote-tracking branch 'origin/dev' into dev 2022-04-11 11:04:02 +08:00
aixianling
698fd5f5f2 BUG 29030 2022-04-11 11:03:46 +08:00
shijingjing
f0a3cf91ad 28986 2022-04-11 10:59:15 +08:00
aixianling
f106c220e3 Merge remote-tracking branch 'origin/dev' into dev
# Conflicts:
#	project/xiushan/apps/financing/AppFinancingNeeds/AppFinancingNeeds.vue
2022-04-11 10:58:42 +08:00
aixianling
8502f94796 BUG 29018 2022-04-11 10:57:21 +08:00
liuye
61e30c8dbe 融资统计 2022-04-11 10:54:05 +08:00
liuye
4a138c52a6 组织id 2022-04-11 10:42:42 +08:00
liuye
2ef7f2a91d 29022 2022-04-11 10:26:58 +08:00
aixianling
4d16c8c2cc Merge remote-tracking branch 'origin/dev' into dev 2022-04-11 10:14:31 +08:00
aixianling
63649d631f BUG 29015 2022-04-11 10:13:48 +08:00
liuye
87c0493629 bug 2022-04-11 10:05:34 +08:00
liuye
09d107514b 金融机构查询 2022-04-11 09:50:44 +08:00
liuye
8cf11b7167 29016 2022-04-11 09:41:29 +08:00
shijingjing
0c7c690af1 29010 2022-04-11 08:59:32 +08:00
aixianling
499dcfb026 BUG 28997 2022-04-08 21:21:18 +08:00
aixianling
cf2e255253 Merge remote-tracking branch 'origin/dev' into dev 2022-04-08 21:19:07 +08:00
aixianling
446facac7e 下次坚决不听你们说迁移积分应用了 2022-04-08 21:18:52 +08:00
shijingjing
bf8bd66b85 29001 2022-04-08 21:10:11 +08:00
liuye
db814b24de 融资统计 2022-04-08 21:09:38 +08:00
aixianling
5c309c0321 调整企业文字logo 2022-04-08 21:06:25 +08:00
shijingjing
0e2c0cb3b5 宽度 2022-04-08 20:51:37 +08:00
shijingjing
5b1fc1317d 表格 2022-04-08 20:49:00 +08:00
aixianling
dc1d009dad 抽取企业详情组件 2022-04-08 20:47:13 +08:00
aixianling
dcfa2eeada 抽取企业详情组件 2022-04-08 20:33:58 +08:00
shijingjing
4b5d7459f4 信用代码 2022-04-08 20:31:06 +08:00
shijingjing
5da70389cc 公共事业欠费 2022-04-08 20:28:35 +08:00
aixianling
c4b6b382ad BUG 28974 2022-04-08 19:16:48 +08:00
aixianling
f8b0290497 BUG 28875 2022-04-08 18:55:33 +08:00
aixianling
c4d579a301 Merge remote-tracking branch 'origin/dev' into dev 2022-04-08 18:37:31 +08:00
aixianling
f05c9703c5 BUG 28972 2022-04-08 18:37:13 +08:00
shijingjing
966a94483a 28994 2022-04-08 18:31:50 +08:00
aixianling
8f1ef4dc7e BUG 28975 2022-04-08 18:30:35 +08:00
aixianling
67d29e2a89 Merge remote-tracking branch 'origin/dev' into dev 2022-04-08 18:15:50 +08:00
aixianling
d9f873a399 信贷统计完成 2022-04-08 18:15:36 +08:00
shijingjing
55afb5b471 28991 2022-04-08 18:07:36 +08:00
shijingjing
f8cfb45fa2 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-04-08 18:01:17 +08:00
shijingjing
4875195a90 28991 2022-04-08 18:00:10 +08:00
aixianling
3d6b1c9b7c Merge remote-tracking branch 'origin/dev' into dev 2022-04-08 17:59:00 +08:00
aixianling
999e1c895e 统计基本完成 2022-04-08 17:58:47 +08:00
shijingjing
ecb6a02a46 28948 2022-04-08 17:43:02 +08:00
shijingjing
a0c42b0053 28985 2022-04-08 17:26:50 +08:00
yanran200730
c429617241 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-04-08 17:25:16 +08:00
yanran200730
38de1f36f2 bug 2022-04-08 17:25:08 +08:00
shijingjing
c46a1c7e26 28983 28984 2022-04-08 17:20:18 +08:00
aixianling
7e63f5d911 Merge remote-tracking branch 'origin/dev' into dev 2022-04-08 17:08:06 +08:00
aixianling
67166d2b25 秀山接入大屏设计 2022-04-08 17:07:49 +08:00
liuye
fa8967084c ct 2022-04-08 17:07:17 +08:00
liuye
8ef80e4f0d 字典 2022-04-08 17:06:50 +08:00
shijingjing
645034f0af 28946 2022-04-08 17:04:23 +08:00
shijingjing
7bedfeca11 28981 2022-04-08 16:48:09 +08:00
shijingjing
fd2bbcb344 28980 2022-04-08 16:45:03 +08:00
shijingjing
8a31e47e7b bug 2022-04-08 15:58:38 +08:00
shijingjing
f557e5222c 股权总数 股金总额 2022-04-08 15:54:26 +08:00
shijingjing
5b2b5eb799 bug 2022-04-08 15:30:39 +08:00
shijingjing
c1aa8bfa1d 28965 2022-04-08 15:08:22 +08:00
shijingjing
a5859f0077 28962 2022-04-08 15:05:10 +08:00
shijingjing
b386c5d952 28946 2022-04-08 15:02:39 +08:00
shijingjing
7c0874b7b3 滚动条 2022-04-08 14:54:29 +08:00
shijingjing
821236713c 右侧滚动条 2022-04-08 14:49:41 +08:00
shijingjing
d0ed71cf8f 28948 2022-04-08 14:36:51 +08:00
shijingjing
a02e127a42 28950 2022-04-08 14:19:09 +08:00
liuye
43f1e688e1 bug 2022-04-08 14:17:34 +08:00
shijingjing
ec853d63f1 导入 2022-04-08 14:13:05 +08:00
shijingjing
43b3e253b6 集体股权 2022-04-08 14:12:06 +08:00
aixianling
abed0e85dd Merge remote-tracking branch 'origin/dev' into dev 2022-04-08 11:54:17 +08:00
aixianling
3398d39e11 企业微信配置调优 2022-04-08 11:53:59 +08:00
liuye
510f9f14b1 bug 2022-04-08 11:49:59 +08:00
shijingjing
3c8104554a 集体经济股权 2022-04-08 11:30:42 +08:00
aixianling
ce55f3db03 积分规则需求变更 2022-04-08 10:34:23 +08:00
aixianling
5da77df064 贷款审批调整界面 2022-04-08 10:10:59 +08:00
aixianling
f3c3b00367 贷款审批调整界面 2022-04-08 10:10:00 +08:00
aixianling
32398ece08 贷款审批调整界面 2022-04-08 10:08:23 +08:00
shijingjing
bf3eda9a10 土地流转 宅基地管理 模糊查询 2022-04-08 09:08:44 +08:00
liuye
4de7b17f57 地区 2022-04-07 21:12:41 +08:00
shijingjing
8165380828 28935 2022-04-07 20:41:16 +08:00
liuye
11465a2190 28938 2022-04-07 20:11:01 +08:00
liuye
dc27ac30e9 bug· 2022-04-07 19:47:59 +08:00
shijingjing
478b4025a7 宅基地增删改查 2022-04-07 18:46:45 +08:00
liuye
037da98f84 需求 2022-04-07 18:44:33 +08:00
liuye
5dadee4a3a ct 2022-04-07 18:36:03 +08:00
liuye
aea786945f bug 2022-04-07 18:35:43 +08:00
shijingjing
fb93f70776 土地流转 增删改查 2022-04-07 18:03:54 +08:00
shijingjing
d5acaec0ba 宅基地验证 2022-04-07 15:55:15 +08:00
shijingjing
cbd022aed3 宅基地新增 2022-04-07 15:35:23 +08:00
shijingjing
80617aada2 土地流转 新增 2022-04-07 15:11:49 +08:00
aixianling
bd62cf7b8b Merge remote-tracking branch 'origin/dev' into dev 2022-04-07 09:44:10 +08:00
aixianling
3241623df2 推送随手拍样式 2022-04-07 09:43:52 +08:00
yanran200730
3b89905b0b Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-04-06 19:22:14 +08:00
yanran200730
b929880b7a bug 2022-04-06 19:22:09 +08:00
shijingjing
f5ea57d30c 28867 2022-04-06 17:54:35 +08:00
shijingjing
42a386c38a 28868 2022-04-06 17:53:48 +08:00
shijingjing
faf2742b68 28839 2022-04-06 17:50:01 +08:00
shijingjing
c227b0ec34 28857 2022-04-06 16:35:05 +08:00
shijingjing
0a767cef46 type 2022-04-06 16:19:43 +08:00
shijingjing
e37efe0ce0 28849 2022-04-06 16:06:19 +08:00
aixianling
b5b797bab5 Merge remote-tracking branch 'origin/dev' into dev 2022-04-06 15:56:35 +08:00
aixianling
dbdb0601f3 BUG 积分维护 2022-04-06 15:56:14 +08:00
shijingjing
fbd6a41acf 失信新增 2022-04-06 15:48:17 +08:00
shijingjing
21fe0d1b25 信用代码18位 2022-04-06 15:35:27 +08:00
shijingjing
2bafd745b7 28830 2022-04-06 15:30:49 +08:00
shijingjing
8eaef01fb7 28828 2022-04-06 15:29:10 +08:00
shijingjing
58bbec13fe 28838 2022-04-06 15:19:44 +08:00
shijingjing
6bd1423e57 bug 28827 2022-04-06 13:53:39 +08:00
yanran200730
2e92a69c4d Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-04-06 11:59:27 +08:00
yanran200730
e67d711db3 bug 2022-04-06 11:59:21 +08:00
shijingjing
9900189039 土地流转 宅基地 2022-04-06 11:38:35 +08:00
shijingjing
0a30b0b091 样式调整 2022-04-06 10:49:34 +08:00
shijingjing
a480902ce6 失信导入导出 2022-04-06 10:21:41 +08:00
yanran200730
7c413fa9b2 2 2022-04-06 10:19:55 +08:00
shijingjing
35e1dd482e 纳税 2022-04-02 17:53:17 +08:00
shijingjing
4da06c2b26 行政处罚导入导出 2022-04-02 16:32:08 +08:00
shijingjing
9f0f41554b 土地管理列表 2022-04-02 15:16:51 +08:00
shijingjing
546e3dd993 背景色 2022-04-02 15:07:10 +08:00
shijingjing
4d1368ea62 导入 导出 2022-04-02 14:37:44 +08:00
shijingjing
f40382b6d1 纳税等级 2022-04-02 14:13:26 +08:00
shijingjing
b3ec72ac6c 详情 2022-04-02 13:59:27 +08:00
shijingjing
a9aa0c32e8 详情 2022-04-02 11:25:44 +08:00
liuye
4780045b21 企微配置 2022-04-02 10:33:56 +08:00
shijingjing
6294795ab5 纳税 2022-04-01 18:21:35 +08:00
aixianling
8911edde23 Merge remote-tracking branch 'origin/dev' into dev 2022-04-01 17:28:28 +08:00
aixianling
b6b3266a3e 优化打包流程 2022-04-01 17:28:15 +08:00
shijingjing
2d75d69b1e 新增失信人员 2022-04-01 17:21:12 +08:00
aixianling
3dad000a72 Merge remote-tracking branch 'origin/dev' into dev 2022-04-01 16:10:07 +08:00
aixianling
5e5fc139de 优化打包流程 2022-04-01 16:09:49 +08:00
shijingjing
6db56c17a7 行政许可增删查 2022-04-01 15:48:09 +08:00
shijingjing
f831af9f88 详情页 2022-04-01 14:04:05 +08:00
shijingjing
c181c821c1 行政许可 2022-04-01 13:37:56 +08:00
shijingjing
8962d5c1ad 纳税信息 2022-04-01 11:48:01 +08:00
shijingjing
71ca1ebd4b 行政处罚 2022-04-01 11:26:35 +08:00
shijingjing
1bfcccaaec 失信被执行人 2022-04-01 11:03:06 +08:00
shijingjing
1ed3d03e5b 行政许可信息 2022-04-01 09:30:35 +08:00
aixianling
b14c36ce16 优化打包流程 2022-03-31 18:25:28 +08:00
aixianling
fe10a5870c 优化打包流程 2022-03-31 18:23:20 +08:00
yanran200730
3c8988afe2 大屏设计 2022-03-31 17:04:54 +08:00
shijingjing
3e7057e189 股权结构 2022-03-31 16:50:09 +08:00
yanran200730
b10bc5209c Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-31 16:03:52 +08:00
yanran200730
49a2d392ad bug 2022-03-31 16:03:46 +08:00
shijingjing
8f4c2a21b9 股权结构 2022-03-31 15:32:22 +08:00
aixianling
ab3bece353 增加筛选条件和下载部署包方法 2022-03-31 15:28:16 +08:00
aixianling
e84081c42c Merge remote-tracking branch 'origin/dev' into dev 2022-03-31 15:08:32 +08:00
aixianling
d50b295bc7 BUG 28743 2022-03-31 15:08:05 +08:00
shijingjing
725b1eea0c 经营主体 企业类型筛选 认证状态筛选 2022-03-31 14:28:50 +08:00
aixianling
2785af1829 监测对象需求变更完成 2022-03-31 11:05:02 +08:00
aixianling
723fbdce2a Merge remote-tracking branch 'origin/dev' into dev 2022-03-31 09:57:36 +08:00
aixianling
31a3290a7b BUG 28707 2022-03-31 09:57:19 +08:00
yanran200730
27ab36b3ce Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-31 09:10:07 +08:00
yanran200730
94f5713f89 更新 2022-03-31 09:09:38 +08:00
aixianling
4675ebf883 加入git分支 2022-03-31 09:08:03 +08:00
aixianling
5478611712 新增部署发布模块 2022-03-30 19:20:44 +08:00
aixianling
395bc26bb1 BUG 28495 2022-03-30 17:17:01 +08:00
aixianling
df0ac93042 bug 28688 2022-03-30 16:22:11 +08:00
yanran200730
1a616bc084 bug 2022-03-30 10:51:50 +08:00
yanran200730
e6f0c7f004 bug 2022-03-29 18:15:34 +08:00
yanran200730
10f1ffbe4e bug 2022-03-29 18:13:03 +08:00
yanran200730
ae5f41df8c 走访进度 2022-03-29 18:03:29 +08:00
yanran200730
026cabbc16 28652 2022-03-29 17:57:55 +08:00
yanran200730
e960e95e06 28646 2022-03-29 17:49:20 +08:00
yanran200730
d80c3c6092 28572 2022-03-29 17:17:24 +08:00
yanran200730
28d917645d 28603 2022-03-29 17:09:40 +08:00
yanran200730
f4c15159d1 28637 2022-03-29 16:43:09 +08:00
yanran200730
826fb5f4dd 28638 2022-03-29 16:34:27 +08:00
yanran200730
6c338a5dd4 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-29 16:31:17 +08:00
yanran200730
6aa4d5a6d8 28647 2022-03-29 16:31:04 +08:00
aixianling
abd55bd413 BUG 28634 2022-03-29 15:59:47 +08:00
aixianling
a1d439104e BUG 28633 2022-03-29 15:54:50 +08:00
aixianling
087165af50 Merge remote-tracking branch 'origin/dev' into dev 2022-03-29 15:53:53 +08:00
aixianling
d0daec7694 BUG 28632 2022-03-29 15:53:35 +08:00
yanran200730
de2eff8ce6 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-29 14:18:56 +08:00
yanran200730
195a1d460d bug 2022-03-29 14:18:51 +08:00
aixianling
a7f9c41667 Merge remote-tracking branch 'origin/dev' into dev 2022-03-29 13:56:43 +08:00
aixianling
eed93b27b4 BUG 28631 2022-03-29 13:56:21 +08:00
yanran200730
92853d3f5e Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-29 13:41:42 +08:00
yanran200730
47c52e3ef7 大屏数据源配置 2022-03-29 13:41:35 +08:00
aixianling
4c4240e3c8 BUG 28626 2022-03-29 11:49:43 +08:00
aixianling
2d35cdc95a BUG 28622 2022-03-29 10:48:30 +08:00
aixianling
30f28a4941 BUG 28623 2022-03-29 10:47:42 +08:00
aixianling
b1d93bb65f BUG 28614 2022-03-29 09:55:50 +08:00
yanran200730
8f0f4e7106 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-29 09:40:02 +08:00
yanran200730
45a1f53627 bug 2022-03-29 09:39:56 +08:00
aixianling
f3e003dfd6 BUG 28608 2022-03-29 09:29:14 +08:00
aixianling
ace4a8314b BUG 28575 2022-03-29 09:24:05 +08:00
aixianling
780a912b57 Merge remote-tracking branch 'origin/dev' into dev 2022-03-29 09:21:17 +08:00
aixianling
ad0040260e BUG 28600 2022-03-29 09:20:56 +08:00
yanran200730
34631c0668 28588 2022-03-29 09:17:02 +08:00
aixianling
d4ee80b802 Merge remote-tracking branch 'origin/dev' into dev 2022-03-28 18:12:23 +08:00
aixianling
efd0842832 BUG 28607 2022-03-28 18:12:10 +08:00
yanran200730
78c9c2a40c 大屏 数据源管理 2022-03-28 18:01:13 +08:00
yanran200730
746927e826 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-28 17:47:59 +08:00
yanran200730
1089e784db 大屏 2022-03-28 17:47:53 +08:00
aixianling
bfd7c20187 BUG 28599 2022-03-28 17:36:48 +08:00
yanran200730
c955e7016c Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-28 17:29:01 +08:00
yanran200730
0ead6bdffb 视频监控 2022-03-28 17:28:55 +08:00
aixianling
352c573251 BUG 28596 2022-03-28 17:26:45 +08:00
aixianling
4b20cd2dee BUG 28594 2022-03-28 17:22:51 +08:00
aixianling
d7b59ba7e1 BUG 28591 2022-03-28 17:21:54 +08:00
aixianling
d79cb21929 BUG 28593 2022-03-28 17:21:10 +08:00
aixianling
4db6925d38 BUG 28582 2022-03-28 16:59:04 +08:00
aixianling
30047204e1 BUG 28581 2022-03-28 16:57:25 +08:00
aixianling
76154527ef Merge remote-tracking branch 'origin/dev' into dev 2022-03-28 16:49:02 +08:00
aixianling
8879a71b51 BUG 28580 2022-03-28 16:48:41 +08:00
yanran200730
a3dac13b53 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-28 16:41:40 +08:00
yanran200730
5c8e207a57 28579 2022-03-28 16:41:33 +08:00
aixianling
8aae62c071 Merge remote-tracking branch 'origin/dev' into dev 2022-03-28 16:34:02 +08:00
aixianling
84f60ce32f BUG 28576 2022-03-28 16:33:45 +08:00
yanran200730
64c1ae7656 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-28 16:30:52 +08:00
yanran200730
ca3fbd9a89 28570 2022-03-28 16:30:42 +08:00
aixianling
a54d30684d BUG 28568 2022-03-28 16:27:15 +08:00
aixianling
cd21fd3e73 自动路由规则过滤优化 2022-03-28 15:27:07 +08:00
aixianling
2d4edcfc21 Merge remote-tracking branch 'origin/dev' into dev 2022-03-28 14:56:39 +08:00
aixianling
2611a72508 BUG 28556 28553 2022-03-28 14:56:24 +08:00
yanran200730
c4b597c409 统计 2022-03-28 14:23:56 +08:00
yanran200730
92dfebc1d4 28557 2022-03-28 13:54:24 +08:00
yanran200730
0eb5036b11 28536 2022-03-28 10:39:08 +08:00
yanran200730
52c854661a 28550 2022-03-28 10:29:55 +08:00
yanran200730
f160760526 28552 2022-03-28 10:02:31 +08:00
yanran200730
68d5b27194 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-28 09:54:32 +08:00
yanran200730
e37950d54b 28552 2022-03-28 09:54:25 +08:00
aixianling
8f0670265b Merge remote-tracking branch 'origin/dev' into dev 2022-03-26 17:42:37 +08:00
aixianling
a0e2cfc6cf 检测对象完成 2022-03-26 17:41:57 +08:00
aixianling
b0b03d00d4 检测对象完成 2022-03-26 17:41:38 +08:00
yanran200730
66826caf94 统计 2022-03-26 16:59:16 +08:00
yanran200730
9281f18ecb 统计 2022-03-26 16:56:26 +08:00
yanran200730
82778173bb 监测对象 2022-03-26 15:47:24 +08:00
yanran200730
8fe222ba4b 走访情况 2022-03-26 15:34:58 +08:00
yanran200730
88775a9bdb 风险 2022-03-26 14:35:52 +08:00
yanran200730
c2b9333e29 工作考核 2022-03-25 18:41:21 +08:00
yanran200730
29fdd4a222 审批负责人 2022-03-25 18:29:20 +08:00
yanran200730
8650c0dd09 审批负责人 2022-03-25 18:27:05 +08:00
yanran200730
c5c1645054 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-25 18:07:07 +08:00
yanran200730
4ce4dd0a3c bug 2022-03-25 18:06:59 +08:00
aixianling
3503c2314d Merge remote-tracking branch 'origin/dev' into dev 2022-03-25 17:43:42 +08:00
aixianling
9e8e1788fb 监测对象字段对完了 2022-03-25 17:43:22 +08:00
yanran200730
d484770b2f 预警 2022-03-25 17:39:40 +08:00
yanran200730
e6cb2bf706 网格权限 2022-03-25 16:32:22 +08:00
yanran200730
110c909c50 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-25 16:27:29 +08:00
yanran200730
ee58c2b938 监控视频 2022-03-25 16:27:23 +08:00
aixianling
5160f82b65 Merge remote-tracking branch 'origin/dev' into dev 2022-03-25 16:19:10 +08:00
aixianling
9f21513075 取消引入 2022-03-25 16:17:58 +08:00
yanran200730
8505c995ed Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-25 16:16:20 +08:00
yanran200730
5712a7e111 网格员权限 2022-03-25 16:16:14 +08:00
aixianling
374a6a1ddf 尝试一下大屏设计的问题 2022-03-25 16:06:05 +08:00
aixianling
208e6de3e4 尝试一下大屏设计的问题 2022-03-25 16:04:19 +08:00
aixianling
87231fdb1f dvui更换设置 2022-03-25 14:36:46 +08:00
aixianling
760db2bb82 修复异常 2022-03-25 14:18:40 +08:00
aixianling
b1ffe2afde Merge remote-tracking branch 'origin/dev' into dev 2022-03-25 14:17:17 +08:00
aixianling
7640fe085b 修复异常 2022-03-25 14:17:00 +08:00
yanran200730
dd901c005d 网格员 2022-03-25 11:41:15 +08:00
yanran200730
7808526ee7 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-25 11:30:25 +08:00
yanran200730
c94fe15ced 视频监控 2022-03-25 11:29:49 +08:00
aixianling
ce5cb61eb4 Merge remote-tracking branch 'origin/dev' into dev 2022-03-25 11:13:13 +08:00
aixianling
cc87206dbc 迁移大屏UI库和应用 2022-03-25 11:09:26 +08:00
yanran200730
708342d09b Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-25 10:33:26 +08:00
yanran200730
464c5d5663 居民档案导出 2022-03-25 10:33:19 +08:00
aixianling
60bd0b1dff Merge remote-tracking branch 'origin/dev' into dev 2022-03-24 18:23:15 +08:00
aixianling
40efa96ba1 监测对象界面完成 2022-03-24 18:22:55 +08:00
yanran200730
fe3a637255 监控视频 2022-03-24 17:52:58 +08:00
yanran200730
a8db0542d7 视频监控优化 2022-03-24 17:33:39 +08:00
yanran200730
c2d9aa6d06 视频监控 2022-03-24 16:43:02 +08:00
yanran200730
476bc5c74d 接口地址 2022-03-24 16:30:03 +08:00
yanran200730
1ae5558c65 监控视频 2022-03-24 16:29:41 +08:00
yanran200730
8abfcb0e55 28509 2022-03-24 15:18:03 +08:00
yanran200730
06240d2b09 bug 2022-03-24 15:07:54 +08:00
yanran200730
d9701c366d 风险预警 2022-03-24 11:03:26 +08:00
yanran200730
c33eb0e6f2 bug 2022-03-24 09:36:19 +08:00
yanran200730
5f116d6984 接口地址 2022-03-24 09:13:48 +08:00
liuye
d84400e89b ct 2022-03-24 08:44:14 +08:00
liuye
0bbb816f3f 路径 2022-03-24 08:43:07 +08:00
yanran200730
3400df5fd4 bug 2022-03-23 17:44:57 +08:00
yanran200730
9e44eddddf 监控视频 2022-03-23 17:28:30 +08:00
yanran200730
4dad5e1ab2 屏蔽网格员申报 2022-03-23 16:57:02 +08:00
yanran200730
627b4e15cb 28504 2022-03-23 16:51:52 +08:00
yanran200730
ed9ac12226 28421 2022-03-23 16:47:11 +08:00
yanran200730
195dca851c 28412 2022-03-23 16:41:27 +08:00
yanran200730
8589cbe29a 28497 2022-03-23 16:37:49 +08:00
yanran200730
ea63a41b47 28508 2022-03-23 16:21:41 +08:00
yanran200730
76986d7803 视频监控 2022-03-23 14:19:15 +08:00
yanran200730
cbdc4a8b65 视频监控 2022-03-23 13:52:23 +08:00
aixianling
3ca0ba0f11 内容发布详情异常修复 2022-03-23 11:29:39 +08:00
aixianling
3d805694bc 针对上架做产品库登录调整 2022-03-23 11:23:32 +08:00
aixianling
26d3d1e7a7 BUG 28475 2022-03-23 11:11:08 +08:00
aixianling
6ce2044471 BUG 28490 2022-03-23 10:41:53 +08:00
aixianling
6f99497129 BUG 28494 2022-03-23 10:38:28 +08:00
aixianling
ba92b068d8 BUG 28491 2022-03-23 10:26:54 +08:00
aixianling
18a7fead0b BUG 28489 2022-03-23 10:19:19 +08:00
aixianling
111e10b434 BUG 28439 2022-03-23 10:18:00 +08:00
aixianling
934c2b0a78 BUG 28484 2022-03-23 09:58:27 +08:00
aixianling
c50141a411 增加角色权限 2022-03-23 09:47:04 +08:00
aixianling
5c339ccdfa BUG 28493 2022-03-23 09:42:45 +08:00
aixianling
54f71407ad 可查看详情 2022-03-22 22:52:01 +08:00
aixianling
3fe0c5ab05 BUG 28486 2022-03-22 22:38:12 +08:00
aixianling
b86cb09212 BUG 28483 2022-03-22 22:36:52 +08:00
aixianling
a77aff56aa BUG 28484 2022-03-22 22:35:46 +08:00
aixianling
fff005a6a1 BUG 28482 2022-03-22 22:32:04 +08:00
aixianling
e686914023 BUG 28469 2022-03-22 22:11:33 +08:00
aixianling
97ab7c1204 BUG 28481 2022-03-22 22:09:34 +08:00
aixianling
12873f180c BUG 28470 2022-03-22 22:05:45 +08:00
aixianling
941641f917 BUG 28461 2022-03-22 22:02:36 +08:00
aixianling
797342111f BUG 28455 2022-03-22 22:01:16 +08:00
aixianling
199a75971f BUG 28453 2022-03-22 22:00:28 +08:00
aixianling
3ea9d7e23e BUG 28450 2022-03-22 21:41:04 +08:00
aixianling
f478cb6606 BUG 28447 2022-03-22 21:39:58 +08:00
aixianling
99be5be77d BUG 28477 2022-03-22 21:38:12 +08:00
aixianling
0b0bd5729c BUG 28475 2022-03-22 21:35:50 +08:00
aixianling
9e10f2b77c BUG 28456 2022-03-22 21:11:18 +08:00
aixianling
18d2614b13 BUG 28456 2022-03-22 21:01:16 +08:00
aixianling
26177d03d4 BUG 28443 2022-03-22 20:57:09 +08:00
aixianling
af7e1c72a4 清理地区组件 2022-03-22 20:33:07 +08:00
aixianling
bd65a54b2c BUG 28444 2022-03-22 20:26:57 +08:00
aixianling
d4c11d65e6 调整金融机构 2022-03-22 19:44:04 +08:00
aixianling
6bbc40ef41 积分继续调整 2022-03-22 19:39:23 +08:00
aixianling
26f96dd6b1 贷款审核调整 2022-03-22 19:25:45 +08:00
aixianling
d2f1b25b67 积分统计基本完成 2022-03-22 19:08:56 +08:00
aixianling
afe315af26 推荐产品修复 2022-03-22 18:47:30 +08:00
aixianling
c84bb0fbdc Merge remote-tracking branch 'origin/dev' into dev 2022-03-22 18:41:27 +08:00
aixianling
f45692df45 推荐产品完成 2022-03-22 18:41:13 +08:00
yanran200730
7bcf923c64 28432 2022-03-22 17:58:53 +08:00
yanran200730
1ddf31185c bug 2022-03-22 17:51:57 +08:00
yanran200730
1b290214f6 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-22 17:31:11 +08:00
yanran200730
07e4320b23 查询组件 2022-03-22 17:31:05 +08:00
aixianling
433ff4476f 积分应用暂时修改 2022-03-22 17:20:15 +08:00
aixianling
900ff5ce83 Merge remote-tracking branch 'origin/dev' into dev 2022-03-22 16:46:14 +08:00
aixianling
edbf34a2e3 视频宣传 2022-03-22 16:46:00 +08:00
yanran200730
f55b55e406 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-22 16:17:41 +08:00
yanran200730
9282baa7fa 28338 2022-03-22 16:17:28 +08:00
aixianling
30ecf5b154 群众留言完成 2022-03-22 15:24:33 +08:00
aixianling
25fddf63db Merge remote-tracking branch 'origin/dev' into dev 2022-03-22 15:07:06 +08:00
aixianling
59d1e952d5 接入动态表单模块 2022-03-22 15:06:52 +08:00
yanran200730
a6dafbff38 28368 2022-03-22 14:37:11 +08:00
yanran200730
b3b46e6724 28384 2022-03-22 14:19:23 +08:00
yanran200730
7291113d2f Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-22 11:33:04 +08:00
yanran200730
d0bc1c1508 28414 2022-03-22 11:32:59 +08:00
aixianling
2c5026145d 迁移积分应用 2022-03-22 10:05:15 +08:00
aixianling
729d644e8b 先提交一波群众留言 2022-03-21 21:29:06 +08:00
yanran200730
5364c2571a 28338 2022-03-21 20:11:20 +08:00
yanran200730
f0c1efb4b1 会议通知 2022-03-21 15:58:39 +08:00
yanran200730
39ff23507b bug 2022-03-21 15:52:53 +08:00
yanran200730
f4514c087b 28379 2022-03-21 15:48:43 +08:00
yanran200730
4f5cea34b3 28379 2022-03-21 15:47:20 +08:00
yanran200730
19e3b730db 28383 2022-03-21 15:04:44 +08:00
yanran200730
d8e4916bbc 28383 2022-03-21 15:01:54 +08:00
yanran200730
9039ece985 28384 2022-03-21 14:31:06 +08:00
yanran200730
7ef72ab71e 28321 2022-03-21 14:01:55 +08:00
yanran200730
01248798a7 导出 2022-03-21 13:59:03 +08:00
yanran200730
16db054fb9 28366 2022-03-21 11:15:34 +08:00
yanran200730
fd104efd54 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-21 08:33:12 +08:00
yanran200730
9f2343075a 山东移动需求变更 2022-03-21 08:33:05 +08:00
aixianling
ba709d089c Merge remote-tracking branch 'origin/dev' into dev 2022-03-18 17:06:15 +08:00
aixianling
f2c152a3fc BUG 28357 2022-03-18 17:05:04 +08:00
yanran200730
872d05f47a 导航配置 2022-03-18 16:54:09 +08:00
yanran200730
b9159b8e15 清除多余代码 2022-03-18 15:05:47 +08:00
yanran200730
e67e0fbb82 内容发布新增审核功能 2022-03-18 14:31:08 +08:00
yanran200730
af65ba44ab 内容发布 2022-03-18 13:47:44 +08:00
yanran200730
a93b78de4f 网格员申办 2022-03-18 10:58:11 +08:00
yanran200730
585b2fcf85 特殊人群详情bug 2022-03-18 09:10:20 +08:00
yanran200730
fa608965ba bug 2022-03-18 09:07:56 +08:00
yanran200730
fee4c0c28f 特殊人群 2022-03-17 17:48:49 +08:00
yanran200730
63ce994265 28332 2022-03-17 17:42:20 +08:00
yanran200730
214ced7029 28307 2022-03-17 17:30:24 +08:00
yanran200730
fffb87b45f 27140 2022-03-16 15:43:01 +08:00
yanran200730
8099941802 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-16 15:31:40 +08:00
yanran200730
5f4b48eba7 28269 2022-03-16 15:31:34 +08:00
aixianling
92249196a4 BUG 28264 2022-03-16 12:02:38 +08:00
yanran200730
458b03dd0c 28216 2022-03-15 17:51:34 +08:00
yanran200730
82bfdc6c3c 28246 2022-03-15 17:23:34 +08:00
yanran200730
8d354eee32 28215 2022-03-15 16:14:41 +08:00
yanran200730
38c5ae5e25 28239 2022-03-15 16:11:03 +08:00
yanran200730
77625d872f 28238 2022-03-15 16:06:47 +08:00
yanran200730
091a2761cf 28239 2022-03-15 16:03:15 +08:00
yanran200730
dff68edcbb 28242 2022-03-15 15:57:56 +08:00
yanran200730
2ffc1d06cf 山东移动新增需求 2022-03-15 11:36:15 +08:00
yanran200730
2fe8814dce 居民档案屏蔽导出功能 2022-03-15 10:41:43 +08:00
yanran200730
9ee83ea972 28209 2022-03-15 09:48:03 +08:00
yanran200730
7879070993 28211 2022-03-15 09:45:30 +08:00
yanran200730
0af394b0ed Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-15 09:36:33 +08:00
yanran200730
53397bcdbf 28189 2022-03-15 09:36:28 +08:00
aixianling
36bde01ed9 BUG 28165 2022-03-15 09:34:01 +08:00
aixianling
0df2fcbee3 BUG 28183 2022-03-14 20:38:05 +08:00
aixianling
721a351708 Merge remote-tracking branch 'origin/dev' into dev 2022-03-14 18:08:15 +08:00
aixianling
057c45869a BUG 28166 2022-03-14 18:07:54 +08:00
yanran200730
fa6ccb5cde Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-14 17:44:37 +08:00
yanran200730
1384f7495c 28161 2022-03-14 17:44:31 +08:00
aixianling
c3be9537bd 调整屏蔽居民档案导出按钮 2022-03-14 17:24:28 +08:00
aixianling
c41730e9a4 山东移动居民档案合并至通用版应用 2022-03-14 16:17:59 +08:00
aixianling
cb2aa2c46a 群众留言界面完成 2022-03-14 15:25:07 +08:00
aixianling
dcbe39d228 接入 意见反馈 2022-03-14 12:22:56 +08:00
aixianling
edf03dbb5d 调整村务公开 2022-03-14 12:21:24 +08:00
aixianling
f2508c5823 调整企业管理 2022-03-14 12:07:48 +08:00
aixianling
66fad244d9 oms接入3.0产品库 2022-03-14 11:38:06 +08:00
aixianling
fcb6bbf956 定制化个人中心 2022-03-14 10:43:58 +08:00
aixianling
41dc57f1ac BUG 28163 2022-03-11 13:48:07 +08:00
yanran200730
0c484a0092 走访慰问、居民档案 2022-03-11 11:19:09 +08:00
yanran200730
610631133a 特殊人群 2022-03-10 12:27:52 +08:00
yanran200730
7f2d6942dc 表单配置 2022-03-09 17:01:16 +08:00
yanran200730
f1d34435e5 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-09 15:19:33 +08:00
yanran200730
ecc1500d50 配置表单 2022-03-09 15:19:28 +08:00
aixianling
22fe4f6373 BUG 28149 2022-03-09 14:43:56 +08:00
aixianling
2f21766b4f Merge remote-tracking branch 'origin/dev' into dev 2022-03-09 14:22:33 +08:00
aixianling
6fe2cafabb 清除异常 2022-03-09 14:22:04 +08:00
yanran200730
975e4599d1 表单配置 2022-03-09 14:20:41 +08:00
aixianling
071666f0fe 产品库升级,不用再改加载路径了 2022-03-09 12:00:24 +08:00
aixianling
7940cffc3c 产品库升级,不用再改加载路径了 2022-03-09 11:58:28 +08:00
aixianling
93b1a3a69d BUG 28137 2022-03-09 09:45:36 +08:00
aixianling
4c8c8d5ab8 Merge remote-tracking branch 'origin/dev' into dev 2022-03-09 09:05:34 +08:00
aixianling
aa426ef1da BUG 28073 2022-03-09 09:05:17 +08:00
刘仕伟
0563fbe718 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-08 18:27:52 +08:00
刘仕伟
a61fd5656e 28057 2022-03-08 18:27:42 +08:00
aixianling
4718b60941 BUG 27673 2022-03-08 17:19:32 +08:00
aixianling
61f8d7fea4 BUG 28137 2022-03-08 17:12:44 +08:00
aixianling
af674d4324 BUG 28125 2022-03-08 14:48:51 +08:00
aixianling
905db58f57 BUG 28124 2022-03-08 14:44:26 +08:00
aixianling
b16720420d BUG 27632 2022-03-08 14:40:56 +08:00
aixianling
74f84fe07b BUG 28086 2022-03-08 14:33:32 +08:00
aixianling
cdd570fae0 BUG 28073 2022-03-08 14:21:38 +08:00
aixianling
65b407e744 BUG 28046 2022-03-08 14:18:45 +08:00
aixianling
37f54ace01 简写部分代码 2022-03-08 11:50:44 +08:00
aixianling
77fbf07625 BUG 27519 2022-03-08 11:20:40 +08:00
yanran200730
7bcc4469cc 28073 2022-03-07 14:00:25 +08:00
yanran200730
9f485e897a Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-07 13:59:15 +08:00
yanran200730
5274499468 28085 2022-03-07 13:59:09 +08:00
aixianling
99ac6ffbad 名字异常 2022-03-07 11:59:19 +08:00
yanran200730
192e143b5c 28039 2022-03-04 17:08:57 +08:00
yanran200730
6fc8928032 28020 2022-03-04 17:06:24 +08:00
yanran200730
d06b22878c 大屏 2022-03-04 15:48:24 +08:00
yanran200730
117153324f Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-04 15:46:27 +08:00
yanran200730
505b41fbd6 1 2022-03-04 15:46:18 +08:00
刘仕伟
8c21b368bd 28017 2022-03-04 09:55:38 +08:00
刘仕伟
961993ae2b bug 2022-03-04 09:19:56 +08:00
刘仕伟
047279fe16 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-03 18:52:02 +08:00
刘仕伟
ebce7fab92 bug 2022-03-03 18:51:57 +08:00
yanran200730
8975cdf0f6 bug 2022-03-03 17:53:11 +08:00
yanran200730
39170c953c 28013 2022-03-03 17:21:53 +08:00
yanran200730
b6e200f635 28013 2022-03-03 17:20:51 +08:00
yanran200730
a183f874b4 28015 2022-03-03 17:18:54 +08:00
yanran200730
f3be7e21c9 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-03 16:39:59 +08:00
yanran200730
920847b105 28020 2022-03-03 16:39:54 +08:00
aixianling
e3aef2c7f2 BUG 28004 2022-03-03 12:04:10 +08:00
aixianling
2fb2334e1d BUG 28002 2022-03-03 12:03:29 +08:00
aixianling
31935a80b9 BUG 27996 2022-03-03 10:37:44 +08:00
aixianling
e303901262 BUG 27988 2022-03-03 10:06:28 +08:00
aixianling
5883f4123e BUG 27987 2022-03-03 09:01:37 +08:00
刘仕伟
38b46442aa 版本管理调整 2022-03-02 18:07:26 +08:00
aixianling
93faabe2f5 补充详情跳详情 2022-03-02 18:04:24 +08:00
aixianling
f9b623b538 BUG 27978 2022-03-02 17:47:54 +08:00
aixianling
22113c33ed Merge remote-tracking branch 'origin/dev' into dev 2022-03-02 17:45:48 +08:00
aixianling
55a0e44d79 BUG 27980 2022-03-02 17:45:33 +08:00
刘仕伟
66093030c2 27979 2022-03-02 17:43:28 +08:00
aixianling
4d30281c5b 增加版本管理 2022-03-02 17:25:35 +08:00
aixianling
b9d07f88c8 BUG 27972 2022-03-02 16:45:47 +08:00
aixianling
fcc4518cb1 BUG 27970 2022-03-02 15:56:24 +08:00
aixianling
8fee098a0a BUG 27969 2022-03-02 15:45:38 +08:00
aixianling
29c6d31eca 调整判断 2022-03-02 14:53:20 +08:00
aixianling
914f1bc4fd BUG 27964 2022-03-02 14:29:57 +08:00
yanran200730
22e6340ba9 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-02 14:07:39 +08:00
yanran200730
1552fa3ba9 入口文件 2022-03-02 14:07:33 +08:00
aixianling
7dbc4146a5 Merge remote-tracking branch 'origin/dev' into dev 2022-03-02 11:01:12 +08:00
aixianling
dd4e0e1260 逻辑调整 2022-03-02 11:00:55 +08:00
刘仕伟
e4398f80df Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-02 10:52:34 +08:00
刘仕伟
ac0ca2966a 27881 2022-03-02 10:52:28 +08:00
aixianling
66fd58a69d BUG 27951 2022-03-02 10:48:46 +08:00
aixianling
9d3378bc93 BUG 27951 2022-03-02 10:48:22 +08:00
aixianling
ff72b0f104 BUG 27907 2022-03-02 10:47:22 +08:00
aixianling
813f299ad1 Merge remote-tracking branch 'origin/dev' into dev 2022-03-02 10:27:53 +08:00
aixianling
5ff593ee0a 调整提示 2022-03-02 10:27:37 +08:00
yanran200730
2237b065c3 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-02 10:06:43 +08:00
yanran200730
7a667e6f2b 27926 2022-03-02 10:06:37 +08:00
刘仕伟
04e043cf9d Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-02 10:05:01 +08:00
刘仕伟
6ce01389c8 27881 2022-03-02 10:04:52 +08:00
yanran200730
15555a9304 bug 2022-03-02 10:01:43 +08:00
aixianling
375574a901 bug 27937 2022-03-02 09:52:05 +08:00
aixianling
7cc8089813 BUG 27935 2022-03-02 09:31:09 +08:00
aixianling
26aa5377c5 BUG 27907 2022-03-02 09:28:11 +08:00
aixianling
7a3e6ceb8f 山东移动接入党建模块 2022-03-02 09:21:41 +08:00
aixianling
57ceab5d13 接入党史题库 2022-03-02 09:07:45 +08:00
aixianling
27445b1bba Merge remote-tracking branch 'origin/dev' into dev 2022-03-02 09:01:47 +08:00
aixianling
a0f8e79c85 BUG 27890 2022-03-02 09:01:28 +08:00
刘仕伟
e86d35858c 27879 2022-03-01 19:55:36 +08:00
刘仕伟
3031392f89 单个分配 2022-03-01 19:31:39 +08:00
刘仕伟
c79fc16b0a 功能分配 2022-03-01 19:13:25 +08:00
aixianling
252ead5945 BUG 27920 2022-03-01 18:28:48 +08:00
aixianling
0d7f0ad424 BUG 27918 2022-03-01 18:27:10 +08:00
aixianling
22d951a7b2 BUG 27917 2022-03-01 18:26:22 +08:00
aixianling
3feed4ee0f BUG 27913 2022-03-01 18:22:28 +08:00
aixianling
cbdbae2c57 BUG 27872 2022-03-01 18:18:14 +08:00
aixianling
c58c7140d0 Merge remote-tracking branch 'origin/dev' into dev 2022-03-01 18:16:45 +08:00
aixianling
f0aa42b8f3 BUG 27803 2022-03-01 18:16:14 +08:00
刘仕伟
05e92437c8 27921 2022-03-01 18:10:26 +08:00
刘仕伟
eda06af5c4 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-01 15:46:43 +08:00
刘仕伟
5d8cdf3bb6 27898 2022-03-01 15:46:40 +08:00
aixianling
e98d1babd2 BUG 27830 2022-03-01 15:28:42 +08:00
aixianling
7a87dd25d2 BUG 27827 2022-03-01 15:27:33 +08:00
aixianling
7bcee2b1b6 BUG 27826 2022-03-01 15:26:06 +08:00
aixianling
57a9d329ba BUG 27825 2022-03-01 15:23:02 +08:00
aixianling
8936a026df BUG 27822 2022-03-01 15:21:52 +08:00
aixianling
727d05f861 BUG 27822 2022-03-01 15:19:25 +08:00
aixianling
d6201819c1 BUG 27852 2022-03-01 14:58:14 +08:00
aixianling
e1a89b5d78 BUG 27853 2022-03-01 14:54:17 +08:00
aixianling
b15eca92a4 BUG 27872 2022-03-01 14:52:06 +08:00
aixianling
08a7208cc4 BUG 27873 2022-03-01 14:47:39 +08:00
aixianling
9c0019087b BUG 27900 2022-03-01 14:41:49 +08:00
aixianling
349a869311 BUG 27894 2022-03-01 14:40:17 +08:00
aixianling
02d6343d8e BUG 27894 2022-03-01 14:40:00 +08:00
aixianling
3880e8bc0f BUG 27895 2022-03-01 14:39:29 +08:00
aixianling
570c6cf82c BUG 27892 2022-03-01 14:37:00 +08:00
aixianling
1a7e06f480 BUG 27844 2022-03-01 14:22:26 +08:00
aixianling
70aa2ef31e BUG 27847 2022-03-01 14:18:45 +08:00
aixianling
a251149452 BUG 27803 2022-03-01 14:14:29 +08:00
aixianling
9d1e81b492 BUG 27840 2022-03-01 14:10:57 +08:00
aixianling
4ac2f5a134 BUG 27835 2022-03-01 12:17:18 +08:00
aixianling
c6b293d4bd BUG 27833 2022-03-01 12:13:59 +08:00
aixianling
2e7adce3db Merge remote-tracking branch 'origin/dev' into dev 2022-03-01 12:10:40 +08:00
aixianling
30965d9bdf BUG 27881 2022-03-01 12:10:26 +08:00
刘仕伟
19e82479e4 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-01 12:02:37 +08:00
刘仕伟
6d7492cebe 去掉areaId 2022-03-01 12:02:32 +08:00
aixianling
6f5d6c6ee7 BUG 27803 2022-03-01 12:00:13 +08:00
aixianling
e887776b57 BUG 27790 2022-03-01 11:58:30 +08:00
aixianling
6f1b930a54 BUG 27782 2022-03-01 11:57:51 +08:00
aixianling
6618bc07cb BUG 27773 2022-03-01 11:56:58 +08:00
aixianling
9fefb8fe7e BUG 27749 2022-03-01 11:55:29 +08:00
aixianling
1b70874b25 BUG 27802 2022-03-01 11:54:22 +08:00
aixianling
54f35593d3 Merge remote-tracking branch 'origin/dev' into dev 2022-03-01 11:19:57 +08:00
aixianling
d2244a049c BUG 27801 2022-03-01 11:19:44 +08:00
刘仕伟
a64d93f2e6 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-03-01 11:06:40 +08:00
刘仕伟
1188f2532e 27869 2022-03-01 11:06:37 +08:00
aixianling
f32f109095 BUG 27811 2022-03-01 10:36:47 +08:00
aixianling
f20a2d8146 BUG 27793 2022-03-01 10:34:44 +08:00
aixianling
d6ca31c7b1 BUG 27783 2022-03-01 10:31:18 +08:00
aixianling
adac56a1c1 BUG 27779 2022-03-01 10:30:01 +08:00
aixianling
f01a37a883 BUG 27778 2022-03-01 10:28:54 +08:00
aixianling
3c7983bf65 BUG 27776 2022-03-01 10:27:50 +08:00
aixianling
c0a7716606 BUG 27748 2022-03-01 10:24:16 +08:00
aixianling
04b2f02a13 BUG 27747 2022-03-01 10:15:44 +08:00
aixianling
47c22cb822 Merge remote-tracking branch 'origin/dev' into dev 2022-03-01 10:04:09 +08:00
aixianling
c01c66c8ca BUG 27819 2022-03-01 10:03:49 +08:00
刘仕伟
00bd53dd3a 设置最热 2022-03-01 10:01:03 +08:00
刘仕伟
d9ba2bc1c5 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-02-28 18:09:24 +08:00
刘仕伟
8790f07496 27816 2022-02-28 18:09:21 +08:00
yanran200730
7381b11f0f 27614 2022-02-28 17:53:46 +08:00
刘仕伟
5b668855f3 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-02-28 17:48:48 +08:00
刘仕伟
7c187894b3 审批意见 2022-02-28 17:48:45 +08:00
yanran200730
6818260611 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev
# Conflicts:
#	examples/entries.js
2022-02-28 17:16:09 +08:00
yanran200730
0f96320a9b 27658 2022-02-28 17:15:31 +08:00
刘仕伟
73bfdcb4c3 27791 2022-02-28 17:08:55 +08:00
刘仕伟
835502ba9f 27794 2022-02-28 16:56:04 +08:00
刘仕伟
6f395305bf 27799 2022-02-28 16:54:50 +08:00
刘仕伟
6a70b457de 27804 2022-02-28 16:49:12 +08:00
刘仕伟
82d8c9a826 27797 2022-02-28 16:32:49 +08:00
刘仕伟
1c884e1b1b Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-02-28 16:25:39 +08:00
刘仕伟
da306f69ea 新闻调整 2022-02-28 16:25:36 +08:00
yanran200730
fd7897694c 27638 2022-02-28 10:16:21 +08:00
yanran200730
0eddd90703 27480 2022-02-28 10:06:44 +08:00
yanran200730
0da9b78a13 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-02-28 10:03:59 +08:00
yanran200730
3c44b2580d 27723 2022-02-28 10:03:53 +08:00
刘仕伟
82b11cd362 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-02-28 10:01:29 +08:00
刘仕伟
0369ac26db 调整权限 2022-02-28 10:01:25 +08:00
aixianling
1f17f126d0 经营主体账号改造完成 2022-02-25 18:13:30 +08:00
aixianling
cb60468d0e 新闻中心已完成 2022-02-25 17:27:11 +08:00
aixianling
05d923b924 Merge remote-tracking branch 'origin/dev' into dev 2022-02-25 15:59:26 +08:00
aixianling
f52201095f 数据公示下架 2022-02-25 15:59:05 +08:00
yanran200730
cbc608e3dd 27707 2022-02-25 14:40:31 +08:00
yanran200730
845019c1c3 27681 2022-02-25 14:38:40 +08:00
yanran200730
c5fa3901e1 27582 2022-02-25 14:35:50 +08:00
yanran200730
769e12aac1 27653 2022-02-25 14:33:12 +08:00
yanran200730
40f8cf4984 27622 2022-02-25 14:31:22 +08:00
yanran200730
916129957e 27635 2022-02-25 14:21:47 +08:00
yanran200730
5086a196f8 27637 2022-02-25 14:13:10 +08:00
aixianling
28a466a5d4 样式补充 2022-02-25 14:08:38 +08:00
aixianling
4370c8d923 跳转抢单界面 2022-02-25 14:02:38 +08:00
aixianling
85b51faa89 补充修复 2022-02-25 13:50:14 +08:00
aixianling
f71db402d3 抢单记录完成 2022-02-25 11:52:22 +08:00
aixianling
ce01784c46 抢单记录完成 2022-02-25 11:46:39 +08:00
aixianling
502239ac2e 抢单记录完成 2022-02-25 11:46:21 +08:00
aixianling
397cde8383 更正贷款应用名 2022-02-25 10:32:47 +08:00
aixianling
164203adab 融资需求核对完成 2022-02-25 10:07:29 +08:00
aixianling
829f03e68c 贷款完成 2022-02-25 09:36:07 +08:00
刘仕伟
c228161701 轮播图 2022-02-24 14:54:48 +08:00
刘仕伟
9fa1d90c15 BUG 2022-02-23 13:12:30 +00:00
aixianling
9fa78fa280 贷款审核基本完成 2022-02-23 20:11:38 +08:00
aixianling
864dca4525 产品 2022-02-23 18:49:17 +08:00
aixianling
0e9ef44843 经营主体修复 2022-02-23 18:48:02 +08:00
aixianling
86eaa9178e 经营主体修复 2022-02-23 16:37:58 +08:00
aixianling
01a10159ff 经营主体审核修复 2022-02-23 16:32:19 +08:00
aixianling
58e8f0fd71 经营主体审核修复 2022-02-23 16:26:37 +08:00
aixianling
016eb5a75c 金融机构成员修复 2022-02-23 16:23:10 +08:00
aixianling
e78cc0cbe5 金融机构成员修复 2022-02-23 16:22:26 +08:00
aixianling
f1f928dd39 金融机构成员修复 2022-02-23 16:17:59 +08:00
aixianling
0c403ae92b 智能搜索字段修复 2022-02-23 16:05:17 +08:00
aixianling
6f66cc7503 修复金融机构异常 2022-02-23 15:50:51 +08:00
aixianling
1365cea288 抢单记录页面完成 2022-02-23 09:56:01 +08:00
aixianling
be19bc7005 融资需求池 页面完成 2022-02-23 09:24:55 +08:00
aixianling
f47e6c9acb 金融机构成员完成 2022-02-22 20:48:07 +08:00
aixianling
3982ed8b04 金融机构完成 2022-02-22 19:50:36 +08:00
aixianling
0a50030333 核对一波字典 2022-02-22 19:33:06 +08:00
aixianling
4ec69ad495 贷款审核页面完成 2022-02-22 19:00:42 +08:00
aixianling
b3cd8f7a88 金融产品页面完成 2022-02-22 18:40:57 +08:00
aixianling
6b873efacf 经营主体完成 2022-02-22 17:09:44 +08:00
aixianling
2c16718a9c 经营主体审批基本完成 2022-02-22 17:05:06 +08:00
aixianling
01c843cde1 用户账号提交一部分 2022-02-22 15:04:03 +08:00
aixianling
4922c3cb2b linux下打包包缺失问题修复尝试3 2022-02-22 14:50:22 +08:00
aixianling
bb6a28867e linux下打包包缺失问题修复尝试2 2022-02-22 14:35:13 +08:00
aixianling
741680265a linux下打包包缺失问题修复尝试 2022-02-22 14:20:37 +08:00
aixianling
efcec7ac90 秀山账号管理完成 2022-02-22 11:35:33 +08:00
aixianling
aae44c489e 秀山账号管理完成 2022-02-22 11:34:52 +08:00
aixianling
70e733a7b5 秀山账号管理完成 2022-02-22 11:31:29 +08:00
aixianling
39c459c04c 山东移动接入便民通讯录 2022-02-22 10:59:52 +08:00
aixianling
94f7cb748d 山东移动接入便民通讯录 2022-02-22 10:59:28 +08:00
aixianling
6803ec7670 山东移动接入小程序导航配置 2022-02-22 10:25:53 +08:00
aixianling
815bee9dcc 数据公示页面上传 2022-02-21 18:11:24 +08:00
aixianling
3884316d22 秀山分包 2022-02-21 15:22:21 +08:00
yanran200730
4106c48877 村民圈 2022-02-18 17:31:10 +08:00
yanran200730
dfd9282d01 积分审核 2022-02-18 16:03:09 +08:00
yanran200730
5c32b8e240 27469 2022-02-18 15:21:54 +08:00
yanran200730
3cd4954d6c 27476 2022-02-18 15:05:33 +08:00
yanran200730
2503ee1947 27473 2022-02-18 14:51:20 +08:00
yanran200730
09cf11a5fc 27471 2022-02-18 14:49:16 +08:00
yanran200730
e98949990a 27470 2022-02-18 14:47:25 +08:00
yanran200730
5f78476130 27479 2022-02-18 14:44:21 +08:00
yanran200730
3c424b63ff 监控 2022-02-18 13:55:01 +08:00
yanran200730
745a22a8e2 村民圈 2022-02-18 13:49:08 +08:00
yanran200730
6b96dfe939 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-02-18 13:44:31 +08:00
yanran200730
fd76ce7ac1 表单 2022-02-18 13:44:25 +08:00
aixianling
d98b1ae982 Merge remote-tracking branch 'origin/dev' into dev 2022-02-18 10:15:17 +08:00
aixianling
8a9e591316 名字里多了一个空格 2022-02-18 10:14:32 +08:00
yanran200730
2a8c3cd45f 表单配置 2022-02-18 08:35:26 +08:00
yanran200730
8c400f9168 村民圈 2022-02-17 17:59:19 +08:00
yanran200730
3dbc129e46 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-02-17 17:39:27 +08:00
yanran200730
99fc7cf835 村民圈 2022-02-17 17:39:21 +08:00
aixianling
54e7daea44 配置主库应用到山东移动分包 2022-02-17 17:08:19 +08:00
aixianling
aa39a450e4 Merge remote-tracking branch 'origin/dev' into dev 2022-02-17 16:28:15 +08:00
aixianling
89a564c2dd 完善统一构建多包发布 2022-02-17 16:27:59 +08:00
yanran200730
c80ef26ad5 村民圈 2022-02-17 16:25:52 +08:00
aixianling
512e30a84b Merge remote-tracking branch 'origin/dev' into dev 2022-02-17 16:15:28 +08:00
aixianling
2491c8e906 统一构建多包发布 2022-02-17 16:15:13 +08:00
yanran200730
1df841804a 动态表单 2022-02-17 15:40:24 +08:00
yanran200730
fe66924093 便民通讯录 2022-02-17 13:42:54 +08:00
yanran200730
3f9b98d32c 积分审核 2022-02-17 09:36:16 +08:00
yanran200730
aecc216dc1 居民审核 2022-02-16 15:04:22 +08:00
yanran200730
165df7ee8a 村民圈 2022-02-15 10:37:07 +08:00
yanran200730
c6839f602a Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-02-14 18:22:57 +08:00
yanran200730
5fd231cf2f 27397 2022-02-14 18:22:51 +08:00
aixianling
a634abfbef Merge remote-tracking branch 'origin/dev' into dev 2022-02-14 18:19:36 +08:00
aixianling
31a496e6b3 BUG 27402 2022-02-14 18:19:10 +08:00
yanran200730
ea52e27e77 27389 2022-02-14 18:13:28 +08:00
yanran200730
18edb3aebc 27403 2022-02-14 18:10:07 +08:00
yanran200730
cce0956e6e 27396 2022-02-14 18:09:00 +08:00
yanran200730
a41dac0467 27381 2022-02-14 18:01:33 +08:00
yanran200730
4a8896a16c 山东移动 2022-02-14 17:48:17 +08:00
yanran200730
bec0762630 27383 2022-02-14 14:32:26 +08:00
yanran200730
20a6f55368 27382 2022-02-14 14:23:26 +08:00
yanran200730
71a0c5e638 27307 2022-02-11 15:25:39 +08:00
yanran200730
df0324f904 网格区块 2022-02-11 14:36:02 +08:00
yanran200730
b8e464e299 27245 2022-02-11 14:34:19 +08:00
yanran200730
c8cb33b723 27245 2022-02-11 14:33:21 +08:00
yanran200730
5acedc6aac 27245 2022-02-11 14:19:24 +08:00
yanran200730
40b6043eed 特殊人群 2022-02-11 14:10:39 +08:00
yanran200730
724b52c538 吸毒人员 2022-02-11 14:09:25 +08:00
yanran200730
8b89646069 精神病人 2022-02-11 14:08:25 +08:00
yanran200730
57564bcc1c 27321 2022-02-11 13:59:17 +08:00
yanran200730
f7d5efd4ae 矛盾调解 2022-02-11 13:48:09 +08:00
yanran200730
f29d9e15c8 27314 2022-02-11 13:47:24 +08:00
yanran200730
a4c6fc3175 27264 2022-02-11 13:38:28 +08:00
yanran200730
41ca00537a 27296 2022-02-11 11:45:58 +08:00
yanran200730
b571982b11 27264 2022-02-11 11:28:16 +08:00
yanran200730
7d31bbe3d0 27262 2022-02-11 10:31:30 +08:00
yanran200730
76af1c2d14 27250 2022-02-11 10:11:55 +08:00
yanran200730
9a68f2ec8a 27248 2022-02-11 10:00:53 +08:00
yanran200730
f1e49518e9 27245 2022-02-11 09:43:57 +08:00
yanran200730
ae4e5e3e78 27229 2022-02-10 18:04:08 +08:00
yanran200730
2cd8f476b6 楼栋统计 2022-02-10 17:59:32 +08:00
yanran200730
badf483642 27223 2022-02-10 17:11:48 +08:00
yanran200730
2af7808ccc 27222 2022-02-10 17:04:41 +08:00
yanran200730
cb6cf2e19f 27220 2022-02-10 17:01:37 +08:00
yanran200730
2ea4771df4 27217 2022-02-10 16:55:40 +08:00
yanran200730
567a0ba434 27195 2022-02-10 15:29:51 +08:00
yanran200730
5374862df7 27194 2022-02-10 15:28:28 +08:00
yanran200730
6a5d923739 27196 2022-02-10 15:26:58 +08:00
yanran200730
fb6fee0ae2 27126 2022-02-10 14:10:48 +08:00
yanran200730
a90dfd3037 27132 2022-02-10 13:59:44 +08:00
yanran200730
9654b024b2 27133 2022-02-10 13:56:54 +08:00
yanran200730
14abe686a4 27159 2022-02-10 13:37:38 +08:00
yanran200730
d1a7c2fd17 27152 2022-02-10 12:03:27 +08:00
yanran200730
de30d29b53 27145 2022-02-10 11:33:33 +08:00
yanran200730
2645898031 27144 2022-02-10 11:31:24 +08:00
yanran200730
d6fc0e005f 27141 2022-02-10 11:30:14 +08:00
yanran200730
ebcb526f60 27143 2022-02-10 11:14:20 +08:00
yanran200730
2900c27c70 27143 2022-02-10 11:12:43 +08:00
yanran200730
7a85950d29 轮播图 2022-02-10 10:42:52 +08:00
yanran200730
e98fd640fa 27136 2022-02-10 10:42:33 +08:00
yanran200730
0ad5cc6fd3 27139 2022-02-10 10:41:09 +08:00
yanran200730
312f09a06e 27137 2022-02-10 10:33:47 +08:00
yanran200730
b007cd13df 走访慰问 2022-02-10 10:13:49 +08:00
yanran200730
ab6624266c 健康上报 2022-02-09 18:28:48 +08:00
yanran200730
01bec4be03 bug 2022-02-09 18:14:22 +08:00
yanran200730
69371730b2 网格 2022-02-09 17:53:23 +08:00
yanran200730
f04f01bdba 网格区块 2022-02-09 17:07:46 +08:00
yanran200730
52f1b5d0ed 特殊人群 2022-02-09 15:13:46 +08:00
yanran200730
7f44ee66fd 特殊人群 2022-02-09 14:59:49 +08:00
yanran200730
407d8d4baa 迁移 2022-02-09 10:15:44 +08:00
yanran200730
8440693bbd 矛盾调解 2022-02-09 09:21:33 +08:00
yanran200730
dc1bfcb1bb 事件上报 2022-02-09 08:16:02 +08:00
yanran200730
9c0f4324da 矛盾调解 2022-02-08 14:57:21 +08:00
yanran200730
22855cf70e 村微上架 2022-02-08 14:50:48 +08:00
yanran200730
bd5de25e4b 健康上报 2022-02-08 09:30:49 +08:00
yanran200730
e6d8b3c6c8 轮播图 2022-02-08 09:09:20 +08:00
yanran200730
e91b292d8b 轮播图 2022-02-08 08:59:11 +08:00
yanran200730
a558bbdfe5 轮播图 2022-02-08 08:53:50 +08:00
yanran200730
9781699c2b 轮播图 2022-02-07 18:04:31 +08:00
yanran200730
2e48b7c427 bug 2022-02-07 17:00:23 +08:00
yanran200730
fe9df9d2c5 bug 2022-02-07 15:05:24 +08:00
yanran200730
07569481f1 27043 2022-02-07 14:42:45 +08:00
yanran200730
ac52cd0d59 27047 2022-02-07 14:38:10 +08:00
yanran200730
c452f12eb9 bug 2022-02-07 13:55:52 +08:00
aixianling
571babf236 BUG 27051 2022-01-28 09:43:59 +08:00
yanran200730
296de1c452 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-01-27 10:03:21 +08:00
yanran200730
394917d3ff 企业微信配置 2022-01-27 10:03:05 +08:00
aixianling
20fc23d183 Merge remote-tracking branch 'origin/dev' into dev 2022-01-26 18:09:39 +08:00
aixianling
af9f54b06a BUG 27038 2022-01-26 18:09:06 +08:00
yanran200730
d66067c1f1 通讯录 2022-01-26 18:05:03 +08:00
yanran200730
f8e1535a52 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-01-26 18:03:50 +08:00
yanran200730
4f10fa559a 通讯录 2022-01-26 18:03:44 +08:00
aixianling
eb769a93a1 BUG 27038 2022-01-26 17:41:48 +08:00
yanran200730
b1cbf09a50 27037 2022-01-26 17:06:15 +08:00
yanran200730
b7a1d77fc1 网格大屏 2022-01-26 16:59:00 +08:00
yanran200730
3f4a61090f Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-01-26 16:43:42 +08:00
yanran200730
c2d156cc16 27035 2022-01-26 16:43:37 +08:00
aixianling
6a472a0092 Merge remote-tracking branch 'origin/dev' into dev 2022-01-26 16:36:31 +08:00
aixianling
e71a1f5d69 迁移轮播图片管理 2022-01-26 16:36:19 +08:00
yanran200730
13f0c0ba15 优化大屏 2022-01-26 16:30:39 +08:00
yanran200730
5b88c90de0 优化 2022-01-26 16:20:16 +08:00
yanran200730
05e9e882f0 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-01-26 16:13:39 +08:00
yanran200730
196c1b112e bug 2022-01-26 16:13:33 +08:00
aixianling
0568882c64 Merge remote-tracking branch 'origin/dev' into dev 2022-01-26 16:12:48 +08:00
aixianling
aff3830463 迁移轮播图片管理 2022-01-26 16:12:37 +08:00
yanran200730
f701080b71 大屏更新 2022-01-26 16:03:55 +08:00
yanran200730
92c9a5c1c2 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-01-26 15:58:20 +08:00
yanran200730
b26d8f71f6 27027 2022-01-26 15:58:14 +08:00
aixianling
bce382fcc1 上架版接入菜单管理,账号角色管理 2022-01-26 15:34:01 +08:00
aixianling
e2ca682872 Merge remote-tracking branch 'origin/dev' into dev 2022-01-26 15:12:21 +08:00
aixianling
b148035c40 BUG 26970 2022-01-26 15:11:56 +08:00
yanran200730
7a9acdb7c1 27016 2022-01-26 14:24:33 +08:00
yanran200730
8d8bb29f13 27015 2022-01-26 14:22:15 +08:00
yanran200730
602b4f06ef 27028 2022-01-26 11:40:44 +08:00
yanran200730
2d45ddf2be 网格员选择器优化 2022-01-26 11:26:09 +08:00
yanran200730
d37554d317 bug 2022-01-26 11:13:51 +08:00
yanran200730
e95360fc81 26929 2022-01-26 11:10:42 +08:00
yanran200730
be95736987 26995 2022-01-26 09:40:43 +08:00
yanran200730
b4d98ab335 bug 2022-01-26 09:09:08 +08:00
yanran200730
979128036c bug 2022-01-26 09:08:39 +08:00
yanran200730
3dcf5d23c4 json编辑器 2022-01-26 09:06:15 +08:00
yanran200730
a74a7c7b1d bug 2022-01-26 08:56:52 +08:00
yanran200730
d982651545 1 2022-01-25 19:42:59 +08:00
yanran200730
664c0e7751 bug 2022-01-25 19:39:34 +08:00
yanran200730
18ad905525 bug 2022-01-25 18:58:53 +08:00
yanran200730
769fa6b534 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-01-25 18:31:29 +08:00
yanran200730
8a06bea864 大屏 2022-01-25 18:31:23 +08:00
aixianling
0c55497fb3 BUG 27025 2022-01-25 18:11:05 +08:00
aixianling
636e396303 Merge remote-tracking branch 'origin/dev' into dev 2022-01-25 17:53:50 +08:00
aixianling
3c0a4c9372 BUG 27019 2022-01-25 17:53:38 +08:00
yanran200730
e7b02865fc bug 2022-01-25 17:36:00 +08:00
yanran200730
99b451ac8e Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-01-25 17:09:28 +08:00
yanran200730
145c1bb2d2 bug 2022-01-25 17:09:22 +08:00
aixianling
33d69091f8 Merge remote-tracking branch 'origin/dev' into dev 2022-01-25 17:06:55 +08:00
aixianling
48fa10a21b BUG 26973 2022-01-25 17:06:41 +08:00
yanran200730
6e0c8efbf4 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-01-25 17:03:42 +08:00
yanran200730
db27bfd8f2 bug 2022-01-25 17:03:36 +08:00
aixianling
2a43a20531 BUG 26974 2022-01-25 16:23:40 +08:00
yanran200730
958c7107ce 网格大屏优化 2022-01-25 15:48:22 +08:00
yanran200730
d734a5063c bug 2022-01-25 14:42:41 +08:00
yanran200730
9ca98d43ee bug 2022-01-25 14:24:42 +08:00
yanran200730
211d3f9ac7 大屏 2022-01-25 11:05:45 +08:00
yanran200730
b5e1cfb4fa 26891 2022-01-24 17:55:28 +08:00
yanran200730
72cff8560b 27013 2022-01-24 17:37:25 +08:00
yanran200730
1caf337e60 bug 2022-01-24 17:11:06 +08:00
yanran200730
b279d2ef2b 26935 2022-01-24 17:03:08 +08:00
yanran200730
2fec5f513e bug 2022-01-24 16:53:21 +08:00
yanran200730
65cca6165c 26956 2022-01-24 16:44:57 +08:00
yanran200730
75c1c0d478 优化 2022-01-24 16:39:17 +08:00
yanran200730
9d4ef66fa5 26980 2022-01-24 15:21:54 +08:00
yanran200730
80adcac8b8 bug 2022-01-24 14:32:57 +08:00
yanran200730
69aca8781d 26996 2022-01-24 14:27:45 +08:00
yanran200730
4a8944cc83 网格大屏 2022-01-24 14:08:10 +08:00
yanran200730
0297cb2187 网格大屏 2022-01-22 14:49:43 +08:00
liuye
69131b57f7 党员管理 2022-01-22 11:13:10 +08:00
liuye
9c700ae28f 课程简介 2022-01-22 09:26:01 +08:00
liuye
b90376286c 26955 2022-01-21 17:06:46 +08:00
liuye
b3992b98a9 26954 2022-01-21 16:59:58 +08:00
liuye
4baae80558 26953 2022-01-21 16:58:26 +08:00
liuye
fda3bf95f1 提示文字 2022-01-21 16:53:09 +08:00
liuye
9e54a0e47e bug 2022-01-21 16:45:20 +08:00
liuye
c14ad320e3 26952 2022-01-21 16:37:32 +08:00
liuye
e544551627 26946 2022-01-21 15:24:41 +08:00
liuye
ba6160f7e2 bug 2022-01-21 14:57:40 +08:00
liuye
9e4ebbf29d bug 2022-01-21 14:19:12 +08:00
liuye
5c02f3702b bug 2022-01-21 11:31:00 +08:00
liuye
01ff6c00be bug 2022-01-21 11:23:46 +08:00
liuye
b45557e366 bug 2022-01-21 11:05:11 +08:00
liuye
8b5e387806 网格管理 2022-01-21 09:18:21 +08:00
liuye
2296fe413b ct 2022-01-21 09:17:45 +08:00
liuye
6135040b52 网格需求 2022-01-21 09:17:21 +08:00
yanran200730
158e3ae50e Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-01-20 17:50:08 +08:00
yanran200730
5e29b75f20 网格 2022-01-20 17:50:02 +08:00
liuye
c77259734a 26911 2022-01-20 16:24:11 +08:00
yanran200730
775eba0b0b Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-01-20 15:25:24 +08:00
yanran200730
de8c4a6fc7 26722 2022-01-20 15:25:19 +08:00
liuye
a792483409 26818 2022-01-20 15:05:53 +08:00
yanran200730
271b24ade6 26431 2022-01-20 14:00:49 +08:00
yanran200730
185f4174d8 bug 2022-01-20 11:45:01 +08:00
yanran200730
dc0d258b3f 26430 2022-01-20 10:42:45 +08:00
yanran200730
d6800add0c Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-01-20 09:52:36 +08:00
yanran200730
952e264949 25609 2022-01-20 09:52:31 +08:00
liuye
0a832e3c4b 撤回 2022-01-20 09:47:50 +08:00
liuye
15c1d01b29 重复次数 2022-01-20 09:47:15 +08:00
yanran200730
555cd377ac bug 2022-01-20 09:34:54 +08:00
yanran200730
b4178e1e49 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-01-20 09:16:39 +08:00
yanran200730
31aba06df6 26880 2022-01-20 09:16:33 +08:00
liuye
6e8e9dfe52 26883 2022-01-19 18:08:02 +08:00
liuye
91441487ed 26889 2022-01-19 18:04:57 +08:00
花有清香月有阴
faa7a42ed1 bug 2022-01-19 16:17:02 +08:00
yanran200730
41c95db700 26857 2022-01-19 09:39:47 +08:00
yanran200730
408eb40cc9 26869 2022-01-19 09:35:02 +08:00
yanran200730
ac4811c507 26868 2022-01-18 18:46:10 +08:00
yanran200730
a53adf001f 26855 2022-01-18 18:40:32 +08:00
yanran200730
23ae3efec1 bug 2022-01-18 18:09:37 +08:00
yanran200730
25900aab78 26864 2022-01-18 18:09:01 +08:00
yanran200730
58b712cda4 26865 2022-01-18 18:08:10 +08:00
yanran200730
6a53c29da5 bug 2022-01-18 17:34:39 +08:00
yanran200730
a7ab45c070 26823 2022-01-18 16:30:08 +08:00
yanran200730
e7c90dbe7e 26802 2022-01-18 16:22:09 +08:00
yanran200730
cd8aef1c06 26804 2022-01-18 16:09:39 +08:00
yanran200730
55b6b0c94a 26826 2022-01-18 15:48:27 +08:00
yanran200730
d74989f048 26805 2022-01-18 15:29:15 +08:00
yanran200730
5b458e177d 26858 2022-01-18 15:28:22 +08:00
yanran200730
a03563f3ed 26823 2022-01-18 15:26:26 +08:00
yanran200730
32f80734fb 26852 2022-01-18 15:08:01 +08:00
yanran200730
4d62b19ebe 26849 2022-01-18 15:01:17 +08:00
yanran200730
7ddfd8d394 26806 2022-01-18 14:51:41 +08:00
yanran200730
f1231284d6 26807 2022-01-18 14:35:18 +08:00
yanran200730
f8d5828960 26805 2022-01-18 14:32:29 +08:00
yanran200730
4bba3674f6 26803 2022-01-18 13:54:27 +08:00
yanran200730
392411fbbc 26791 2022-01-18 13:47:40 +08:00
yanran200730
920484cbd6 26375 2022-01-18 11:57:10 +08:00
yanran200730
0f3ca3bc4e 26375 2022-01-18 11:54:59 +08:00
yanran200730
c31eb17b14 26719 2022-01-18 11:51:07 +08:00
yanran200730
252752e5d4 26303 2022-01-18 11:34:37 +08:00
yanran200730
42e76152b6 26320 2022-01-18 11:19:29 +08:00
yanran200730
f31c158bf3 26299 2022-01-18 11:04:48 +08:00
yanran200830
5b10416a14 报错 2022-01-17 19:45:54 +08:00
yanran200730
661c393ab3 26797 2022-01-17 18:19:17 +08:00
yanran200730
a533a2c845 26814 2022-01-17 17:53:28 +08:00
yanran200730
9b0130e3a7 网格大屏 2022-01-17 17:10:20 +08:00
yanran200730
18406063a9 26787 2022-01-14 18:52:57 +08:00
yanran200730
04fe86fe28 26782 2022-01-14 18:09:16 +08:00
yanran200730
143f583ea5 bug 2022-01-14 17:38:56 +08:00
yanran200730
75bf4c48a2 26745 2022-01-14 17:36:54 +08:00
yanran200730
6c09a8a464 26740 2022-01-14 17:26:40 +08:00
yanran200730
85fefcb74b 26752 2022-01-14 17:25:17 +08:00
yanran200730
f56d427d0d 26753 2022-01-14 17:23:34 +08:00
yanran200730
5d6a962a36 26762 2022-01-14 17:15:01 +08:00
yanran200730
9d4bd598f8 26761 2022-01-14 17:09:22 +08:00
yanran200730
f557ad2d86 会议管理 2022-01-14 13:33:01 +08:00
yanran200730
ff40e53f99 bug 2022-01-14 11:27:07 +08:00
yanran200730
a084f65663 优化 2022-01-14 11:11:21 +08:00
yanran200730
aa73246705 26730 2022-01-14 10:31:41 +08:00
yanran200730
e40058b688 26305 2022-01-14 10:27:33 +08:00
yanran200730
44f563d94e 26729 2022-01-14 10:25:44 +08:00
yanran200730
6da2c9de38 26323 2022-01-14 10:19:00 +08:00
yanran200730
0ec0d2444c 网格管理 2022-01-13 17:59:28 +08:00
yanran200730
bd925ea426 网格员 2022-01-13 17:50:33 +08:00
yanran200730
8ea705ba54 26710 2022-01-13 15:37:19 +08:00
yanran200730
b7327e5613 26682 2022-01-13 15:32:49 +08:00
yanran200730
2dd0c6dfe1 26713 2022-01-13 15:31:33 +08:00
yanran200730
11df20b022 26708 2022-01-13 15:27:51 +08:00
yanran200730
2226b3733b 26705 2022-01-13 15:26:00 +08:00
yanran200730
ad69011405 26720 2022-01-13 15:21:20 +08:00
yanran200730
f091321ac7 网格员-责任家庭 2022-01-13 14:56:49 +08:00
yanran200730
ca29a77dd2 防返贫 2022-01-13 10:22:20 +08:00
yanran200730
bfbb21228e Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-01-13 10:11:17 +08:00
yanran200730
f18f98f3ea 网格 2022-01-13 10:11:10 +08:00
刘仕伟
354db2f937 修改字段长度 2022-01-12 17:51:32 +08:00
yanran200730
3a52cbb083 26687 2022-01-12 17:45:13 +08:00
yanran200730
37ec666235 26686 2022-01-12 17:43:25 +08:00
yanran200730
a8bad5b96f 26684 2022-01-12 17:41:28 +08:00
yanran200730
f01a900c3d 26683 2022-01-12 17:40:29 +08:00
yanran200730
cab34aa178 统计 2022-01-12 17:38:25 +08:00
yanran200730
c685f3c081 26680 2022-01-12 17:37:00 +08:00
yanran200730
75840e02a4 26668 2022-01-12 17:34:02 +08:00
yanran200730
40412844ed 26665 2022-01-12 17:30:43 +08:00
yanran200730
565fb6fcb2 26662 2022-01-12 17:30:00 +08:00
yanran200730
dde67c0626 26681 2022-01-12 17:28:12 +08:00
yanran200730
ff312a5b1d bug 2022-01-12 17:26:16 +08:00
yanran200730
afcfd6caa8 健康上报 2022-01-12 16:42:42 +08:00
yanran200730
41e5b2665a 26669 2022-01-12 16:40:49 +08:00
yanran200730
7d8e50d5c8 26662 2022-01-12 16:37:31 +08:00
yanran200730
327d38f356 26663 2022-01-12 16:35:40 +08:00
yanran200730
e0e4385e35 26664 2022-01-12 16:34:50 +08:00
yanran200730
ec9ef47eb6 26665 2022-01-12 16:34:11 +08:00
yanran200730
b8e09562b1 26677 2022-01-12 16:32:30 +08:00
yanran200730
8d0b8d17a0 26658 2022-01-12 16:30:20 +08:00
yanran200730
befcbf25c8 26657 2022-01-12 16:28:51 +08:00
yanran200730
b818df0599 26655 2022-01-12 16:24:50 +08:00
yanran200730
ac37668cd6 26667 2022-01-12 16:23:13 +08:00
yanran200730
bace1def3d 26653 2022-01-12 16:21:28 +08:00
yanran200730
9715c28362 26652 2022-01-12 16:20:37 +08:00
yanran200730
0d2fb84436 26671 2022-01-12 16:14:40 +08:00
yanran200730
2e729a3394 26671 2022-01-12 16:13:30 +08:00
yanran200730
ac8957511b 26672 2022-01-12 16:12:59 +08:00
yanran200730
f4adb2fab0 26673 2022-01-12 16:12:01 +08:00
yanran200730
97ae55bc1f 26651 2022-01-12 16:11:08 +08:00
yanran200730
9ab95599ab 26650 2022-01-12 16:09:31 +08:00
yanran200730
b967fbd71a 26648 2022-01-12 16:08:34 +08:00
yanran200730
eca0aeb263 高风险地区 2022-01-12 11:34:02 +08:00
yanran200730
7f56764456 疫情防控 2022-01-12 10:49:10 +08:00
yanran200730
bdfc9cf3c7 疫情防控 2022-01-12 08:36:23 +08:00
yanran200730
3f27a09ffa bug 2022-01-07 18:52:36 +08:00
yanran200730
0de774d55e 26305 2022-01-07 18:15:39 +08:00
yanran200730
58eceb751a bgu 2022-01-07 18:06:45 +08:00
yanran200730
27e24ee0be 26446 2022-01-07 16:34:50 +08:00
yanran200730
65710e72bb content 2022-01-07 16:33:19 +08:00
yanran200730
b73b7e9c61 26516 2022-01-07 16:32:23 +08:00
yanran200730
4b5e0d70b8 居民议事 2022-01-07 13:52:22 +08:00
yanran200730
3ffcd119f7 居民议事 2022-01-07 13:50:29 +08:00
yanran200730
12134cff51 bug 2022-01-07 11:48:19 +08:00
yanran200730
55634c2b4d 26480 2022-01-07 11:43:26 +08:00
yanran200730
ca9913726e 26397 2022-01-07 11:41:43 +08:00
yanran200730
662527611f 26445 2022-01-07 11:36:49 +08:00
yanran200730
d0666073b6 26326 2022-01-07 11:33:20 +08:00
yanran200730
decf828911 26441 2022-01-07 10:59:42 +08:00
yanran200730
8903d4553a 26467 2022-01-07 10:21:56 +08:00
yanran200730
281af87870 26468 2022-01-07 10:20:53 +08:00
yanran200730
bbf3cc1c6c 26469 2022-01-07 10:20:16 +08:00
yanran200730
22dc407215 26470 2022-01-07 10:17:59 +08:00
yanran200730
a86910bc6e 26362 2022-01-07 09:26:00 +08:00
yanran200730
ad0161d8e7 26426 2022-01-07 09:17:24 +08:00
yanran200730
ed9d612e23 26427 2022-01-07 09:16:44 +08:00
yanran200730
fb6a398380 26433 2022-01-07 09:15:15 +08:00
yanran200730
77c480cf89 26435 2022-01-07 09:13:51 +08:00
yanran200730
c09b2a01d5 26437 2022-01-07 09:06:54 +08:00
yanran200730
2aea462902 26443 2022-01-07 08:52:32 +08:00
yanran200730
d4d686b9d1 26446 2022-01-07 08:47:37 +08:00
yanran200730
74c4e9613b 26416 2022-01-06 17:43:24 +08:00
yanran200730
c3eb1db619 26412 2022-01-06 17:38:46 +08:00
yanran200730
3e51259802 26410 2022-01-06 17:33:10 +08:00
yanran200730
16622b5649 26374 2022-01-06 17:31:58 +08:00
yanran200730
b82cf2a0e1 26419 2022-01-06 17:28:41 +08:00
yanran200730
252ea72212 随手拍 2022-01-06 17:06:27 +08:00
yanran200730
06839ecf21 26363 2022-01-06 09:15:13 +08:00
yanran200730
446f80d5fd 26398 2022-01-06 09:04:47 +08:00
yanran200730
4f1f6fb229 26395 2022-01-06 08:59:17 +08:00
yanran200730
6734034782 bug 2022-01-06 08:54:12 +08:00
yanran200730
f18e443338 26374 2022-01-05 18:14:55 +08:00
yanran200730
41857e98ac 26358 2022-01-05 18:11:25 +08:00
yanran200730
8f7cd4fbcc 26349 2022-01-05 18:10:31 +08:00
yanran200730
8a28963138 26361 2022-01-05 18:09:27 +08:00
yanran200730
75b7d3d79a 26356 2022-01-05 17:46:58 +08:00
yanran200730
27ad71a856 26356 2022-01-05 17:46:39 +08:00
yanran200730
b5e65c4086 26355 2022-01-05 17:45:34 +08:00
yanran200730
a4e1dde375 26354 2022-01-05 17:45:04 +08:00
yanran200730
a22e8fa0d5 26352 2022-01-05 17:44:20 +08:00
yanran200730
6328209ffc 26351 2022-01-05 17:39:19 +08:00
yanran200730
4de93ae3b4 26350 2022-01-05 17:38:37 +08:00
yanran200730
d3bc288558 26349 2022-01-05 17:34:41 +08:00
yanran200730
742281f807 26340 2022-01-05 17:33:54 +08:00
yanran200730
d6146ef600 26370 2022-01-05 17:32:45 +08:00
yanran200730
a3b633f510 26364 2022-01-05 17:31:27 +08:00
yanran200730
296fedb89d Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2022-01-05 09:28:47 +08:00
yanran200730
89cad98a82 村民议事 2022-01-05 09:28:41 +08:00
aixianling
4499445db6 BUG 26305 2022-01-04 18:38:27 +08:00
艾贤凌
76484f4b95 BUG 26305 2022-01-04 10:25:31 +00:00
yanran200730
4cbe34c08c 村民议事 2022-01-04 18:03:46 +08:00
yanran200730
945a087f1b 村民议事 2022-01-04 18:02:13 +08:00
aixianling
56e73bf7ad BUG 26199 2021-12-31 18:23:14 +08:00
aixianling
1013f2b29c 功能分配增加防抖 2021-12-31 17:19:59 +08:00
yanran200730
1020513f13 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2021-12-31 16:45:56 +08:00
yanran200730
2fee0695a1 大屏适配 2021-12-31 16:45:49 +08:00
aixianling
5d2c90bbab BUG 26291 2021-12-31 16:38:34 +08:00
aixianling
4f5b1e65aa BUG 26289 2021-12-31 16:37:13 +08:00
aixianling
57b048cba0 BUG 26287 2021-12-31 15:44:18 +08:00
aixianling
454d77a0df BUG 26264 2021-12-31 15:11:45 +08:00
aixianling
309a75a7c8 BUG 26272 2021-12-31 14:54:10 +08:00
aixianling
a0a34eb431 BUG 26273 2021-12-31 14:37:08 +08:00
aixianling
1c60cc9403 BUG 26246 2021-12-31 11:32:40 +08:00
aixianling
f1ba40f33a BUG 26253 2021-12-31 11:30:49 +08:00
aixianling
1e406154d3 BUG 26247 2021-12-31 11:29:26 +08:00
aixianling
01b59534fe BUG 26247 2021-12-31 11:29:18 +08:00
aixianling
73be1b2646 BUG 26199 2021-12-31 11:09:56 +08:00
aixianling
34abb465d2 BUG 26248 2021-12-31 11:06:54 +08:00
刘仕伟
f22eb9a004 同步部门调整 2021-12-30 21:29:03 +08:00
刘仕伟
42255fa183 bug25876 2021-12-30 19:43:32 +08:00
刘仕伟
17ac94b44a 添加客服类型 2021-12-30 17:57:42 +08:00
yanran200730
a744f90b35 走访慰问 2021-12-30 09:27:12 +08:00
yanran200730
1f4bd475ef 26092 2021-12-29 11:34:53 +08:00
yanran200730
60bd2ad03d Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2021-12-29 09:13:17 +08:00
yanran200730
929408e1e5 bug 2021-12-29 09:13:11 +08:00
aixianling
dd7ba62505 Merge remote-tracking branch 'origin/dev' into dev 2021-12-28 17:59:39 +08:00
aixianling
cb9edd72d6 调整菜单目录交互 2021-12-28 17:59:23 +08:00
yanran200730
94dca3d6c4 大屏设计新增图片素材管理 2021-12-28 16:34:27 +08:00
yanran200730
f7add33031 26088 2021-12-28 14:57:49 +08:00
yanran200730
b33e9f8b85 26091 2021-12-28 14:39:17 +08:00
yanran200730
f2fd618255 小程序公告 2021-12-28 14:26:24 +08:00
yanran200730
f8d2ac641e 26121 2021-12-28 14:23:01 +08:00
yanran200730
9d8f35581c 26116 2021-12-28 14:15:56 +08:00
yanran200730
a6300e7163 25619 2021-12-28 14:12:50 +08:00
yanran200730
bba329a41c 大屏设计页面更换json编辑器 2021-12-28 09:45:57 +08:00
yanran200730
0014d989a0 26061 2021-12-27 14:56:44 +08:00
yanran200730
2765b66115 26086 2021-12-27 14:54:43 +08:00
yanran200730
ae2b788a65 26063 2021-12-27 14:53:27 +08:00
yanran200730
087bd470ec Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2021-12-27 14:49:19 +08:00
yanran200730
a8e0988970 26074 2021-12-27 14:49:13 +08:00
aixianling
18b60f9fa2 Merge remote-tracking branch 'origin/dev' into dev 2021-12-27 11:47:37 +08:00
aixianling
ef4c0d20e5 BUG 26056 2021-12-27 11:47:10 +08:00
yanran200730
a9046bb89a 26054 2021-12-27 11:36:44 +08:00
yanran200730
1a611ae18e 26027 2021-12-24 22:56:37 +08:00
yanran200730
31df5592bf 三会一课 2021-12-24 20:21:39 +08:00
yanran200730
11150f2eea 三会一课 2021-12-24 20:12:05 +08:00
yanran200730
1d2510f465 党组织 2021-12-24 20:04:01 +08:00
yanran200730
53df0f957c 内容发布 2021-12-24 20:01:57 +08:00
yanran200730
d6c3c2b130 25623 2021-12-24 19:54:11 +08:00
yanran200730
539311d192 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2021-12-24 19:47:45 +08:00
yanran200730
52b742f503 25623 2021-12-24 19:46:20 +08:00
aixianling
83674cf6bb BUG 26014 2021-12-24 19:45:16 +08:00
yanran200730
63dd7c0fd7 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2021-12-24 18:50:57 +08:00
yanran200730
99f1cbd934 内容发布 2021-12-24 18:50:51 +08:00
aixianling
f29d742a49 Merge remote-tracking branch 'origin/dev' into dev 2021-12-24 18:30:40 +08:00
aixianling
41d5eba0bb BUG 25607 2021-12-24 18:30:25 +08:00
yanran200730
390288d0f4 视频封面 2021-12-24 18:25:01 +08:00
yanran200730
ee39c87bf7 bug 2021-12-24 18:20:22 +08:00
yanran200730
bd4861e4c1 25624 2021-12-24 18:12:00 +08:00
yanran200730
115cd0b4ae Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2021-12-24 17:43:22 +08:00
yanran200730
ce8be993fe 大屏设计 2021-12-24 17:42:51 +08:00
aixianling
c857a9af4d BUG 26003 2021-12-24 17:40:27 +08:00
aixianling
f692f1eca2 BUG 26002 2021-12-24 17:38:01 +08:00
aixianling
2fd57b9404 BUG 25560 2021-12-24 16:32:42 +08:00
aixianling
585d896cc3 BUG 25559 2021-12-24 16:16:05 +08:00
aixianling
2cd746f1d1 BUG 25869 2021-12-24 15:23:43 +08:00
aixianling
8b56199ce7 Merge remote-tracking branch 'origin/dev' into dev 2021-12-24 15:09:27 +08:00
aixianling
cd09934080 BUG 25975 2021-12-24 15:09:16 +08:00
yanran200730
4a7895b0e2 25987 2021-12-24 15:03:32 +08:00
yanran200730
4253d7eb8e 25990 2021-12-24 15:02:30 +08:00
yanran200730
cee0a1112f 25960 2021-12-24 14:48:15 +08:00
yanran200730
053467032d 25709 2021-12-24 14:44:58 +08:00
yanran200730
a7b261a734 问卷表单 2021-12-24 14:43:32 +08:00
yanran200730
816c6505d7 问卷表单 2021-12-24 14:38:44 +08:00
yanran200730
17d08ef94c 25973 2021-12-24 14:38:00 +08:00
yanran200730
009a1a98df 25978 2021-12-24 14:31:25 +08:00
yanran200730
abf728c500 25945 2021-12-24 13:49:51 +08:00
yanran200730
9ec03075eb 居民档案 2021-12-24 13:48:27 +08:00
yanran200730
9b5a92d113 导航配置 新增认证类型 2021-12-24 11:55:33 +08:00
yanran200730
75b9400571 bug 2021-12-24 10:59:19 +08:00
yanran200730
d141f4a908 25629 2021-12-24 10:58:38 +08:00
yanran200730
5370e51f8a 25906 2021-12-24 10:40:02 +08:00
yanran200730
ef9f3c6517 25899 2021-12-24 09:43:56 +08:00
yanran200730
8756b51ab8 内容发布 2021-12-24 09:25:13 +08:00
yanran200730
b355aa642c 特殊人群 2021-12-24 09:19:48 +08:00
yanran200730
27f4a48e92 25868 2021-12-23 19:11:20 +08:00
yanran200730
18182ea5a1 25866 2021-12-23 19:04:19 +08:00
yanran200730
6ec6c4a73e 25871 2021-12-23 19:03:00 +08:00
yanran200730
ac46ebb348 25600 2021-12-23 18:05:50 +08:00
yanran200730
aa1f45e10a 25616 2021-12-23 17:51:51 +08:00
yanran200730
5e51bfaaa4 25855 2021-12-23 17:41:59 +08:00
yanran200730
14578a575e 25841 2021-12-23 17:39:17 +08:00
yanran200730
298c5b9f8a 25843 2021-12-23 17:14:37 +08:00
yanran200730
e93f2d9d42 25845 2021-12-23 16:56:52 +08:00
yanran200730
6e7d0dd8b2 25840 2021-12-23 16:42:20 +08:00
yanran200730
b89ab13f2d 招工就业 2021-12-23 16:37:59 +08:00
yanran200730
196daf7860 招工就业 2021-12-23 16:32:55 +08:00
yanran200730
c39483fb3e 25623 2021-12-23 16:26:28 +08:00
yanran200730
720a36c8de 25624 2021-12-23 16:18:20 +08:00
yanran200730
f48f191273 25667 2021-12-23 16:10:21 +08:00
yanran200730
3b3a728b7d 25571 2021-12-23 16:02:56 +08:00
yanran200730
d42606f99a 三会一课 2021-12-23 15:50:06 +08:00
yanran200730
14da3b1a52 25755 2021-12-23 15:40:09 +08:00
yanran200730
4a33e17110 25775 2021-12-23 15:29:44 +08:00
yanran200730
bdee85e334 25804 2021-12-23 15:21:48 +08:00
yanran200730
376034d4c4 25807 2021-12-23 15:16:40 +08:00
yanran200730
d8a9b2df48 25803 2021-12-23 15:05:59 +08:00
yanran200730
bba21ea9f4 25799 2021-12-23 14:32:37 +08:00
yanran200730
0dc5f5d7b2 25797 2021-12-23 14:19:47 +08:00
yanran200730
5ad75b217f 25561 2021-12-23 14:16:17 +08:00
yanran200730
4ae1b1ec2e 25702 2021-12-23 11:42:10 +08:00
yanran200730
72269da46f 25701 2021-12-23 11:41:39 +08:00
yanran200730
37cfd3fd46 25762 2021-12-23 11:38:58 +08:00
yanran200730
5c8af74966 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2021-12-23 11:19:34 +08:00
yanran200730
de1035eb08 25720 2021-12-23 11:19:26 +08:00
aixianling
563e15136c Merge remote-tracking branch 'origin/dev' into dev 2021-12-22 19:31:55 +08:00
aixianling
49bc304960 更新腾讯地图 2021-12-22 19:31:43 +08:00
yanran200730
ca7d06b6a6 活动统计 2021-12-22 19:10:18 +08:00
yanran200730
1553352c88 25695 2021-12-22 19:04:43 +08:00
yanran200730
87deb83ed5 村民活动 2021-12-22 18:38:15 +08:00
yanran200730
3bff647de9 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2021-12-22 18:36:23 +08:00
yanran200730
d826f0b095 25690 2021-12-22 18:36:17 +08:00
aixianling
49f6fd00d8 BUG 25650 2021-12-22 17:54:28 +08:00
aixianling
a0c77542ea BUG 25578 2021-12-22 17:43:49 +08:00
aixianling
5d1211ba7a BUG 25578 2021-12-22 17:43:33 +08:00
aixianling
40dfe9e804 Merge remote-tracking branch 'origin/dev' into dev 2021-12-22 17:33:36 +08:00
aixianling
224caa595d BUG 25642 2021-12-22 17:33:25 +08:00
yanran200730
16c8a24163 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2021-12-22 17:32:02 +08:00
yanran200730
bc5c90ca47 婚丧嫁娶 2021-12-22 17:31:52 +08:00
aixianling
c239b6aa04 调整摄像头状态 2021-12-22 17:09:00 +08:00
aixianling
c2dd5e8d29 Merge remote-tracking branch 'origin/dev' into dev
# Conflicts:
#	packages/2.0.5/AppGridMap/components/list.vue
2021-12-22 17:08:32 +08:00
aixianling
302674273a 调整摄像头状态 2021-12-22 17:06:27 +08:00
yanran200730
f9cfba00bc 内容发布去掉缩略图 2021-12-22 17:02:55 +08:00
yanran200730
1ed59569e6 25619 2021-12-22 16:55:57 +08:00
yanran200730
a2208f04c3 25618 2021-12-22 16:51:13 +08:00
yanran200730
242bc9a759 25589 2021-12-22 16:46:41 +08:00
yanran200730
980b461d59 25639 2021-12-22 16:45:36 +08:00
yanran200730
9a7399c2b9 25615 2021-12-22 16:37:10 +08:00
yanran200730
def00addab 25613 2021-12-22 16:31:42 +08:00
yanran200730
b8767dfe76 25608 2021-12-22 16:15:38 +08:00
yanran200730
543ed3d746 小程序公告 2021-12-22 15:55:37 +08:00
yanran200730
d4749cbe7a 25556 2021-12-22 15:53:42 +08:00
yanran200730
4f10eb59a9 25554 2021-12-22 15:51:54 +08:00
yanran200730
cf3dc96e0b 25545 2021-12-22 15:49:51 +08:00
yanran200730
96072cf9b0 25543 2021-12-22 15:46:46 +08:00
yanran200730
56ba5a5a89 25598 2021-12-22 15:37:03 +08:00
yanran200730
0833e55c9d 新闻中心 2021-12-22 14:24:17 +08:00
yanran200730
2f1896b7c4 25643 2021-12-22 13:49:29 +08:00
yanran200730
b0021631b4 25617 2021-12-22 13:47:14 +08:00
yanran200730
65779c1fec 25630 2021-12-22 13:45:43 +08:00
yanran200730
defaa13849 25638 2021-12-22 13:40:24 +08:00
yanran200730
751679be2f 25631 2021-12-22 13:38:43 +08:00
yanran200730
f95d7e54f3 25645 2021-12-22 13:37:37 +08:00
yanran200730
11a897c366 25644 2021-12-22 13:35:21 +08:00
yanran200730
b711509609 25627 2021-12-22 13:34:37 +08:00
yanran200730
a2be11dee6 居民活动 2021-12-22 13:33:18 +08:00
yanran200730
7ee751973a 25604 2021-12-22 13:32:38 +08:00
yanran200730
dc8baff6d3 25595 2021-12-22 11:52:35 +08:00
yanran200730
7204db7887 25590 2021-12-22 11:48:11 +08:00
yanran200730
a2ba873ee0 25588 2021-12-22 11:46:22 +08:00
yanran200730
178d7e77a2 25586 2021-12-22 11:44:08 +08:00
yanran200730
24673e87ca 25585 2021-12-22 11:41:43 +08:00
yanran200730
48774e5853 bug 2021-12-22 11:36:50 +08:00
yanran200730
704498ed13 图片上传 2021-12-22 11:35:40 +08:00
yanran200730
75594e3e54 25583 2021-12-22 11:34:04 +08:00
yanran200730
ffbe06071f 25582 2021-12-22 11:30:36 +08:00
yanran200730
2a23f72102 25581 2021-12-22 11:29:02 +08:00
yanran200730
b75a945a7a 25579 2021-12-22 11:27:32 +08:00
yanran200730
ec5ab626d9 25575 2021-12-22 11:24:07 +08:00
yanran200730
96eae682c0 25576 2021-12-22 11:21:32 +08:00
yanran200730
a6d286d62d 25576 2021-12-22 11:14:44 +08:00
yanran200730
3964cc2769 内容发布 2021-12-22 11:05:32 +08:00
yanran200730
543b247d72 25562 2021-12-22 10:57:58 +08:00
yanran200730
92f5b6789e 25557 2021-12-22 10:54:00 +08:00
yanran200730
6e03eaebe4 25544 2021-12-22 10:13:07 +08:00
yanran200730
b0b5796ece 25542 2021-12-22 10:09:38 +08:00
yanran200730
627d688c2d 导航配置 2021-12-22 09:56:07 +08:00
yanran200730
062af00b20 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2021-12-22 09:48:46 +08:00
yanran200730
f59c178d65 导航配置 2021-12-22 09:48:39 +08:00
aixianling
aeab27e00c Merge remote-tracking branch 'origin/dev' into dev 2021-12-21 18:31:12 +08:00
aixianling
d9fed5e75f 清除党史教育 2021-12-21 18:31:01 +08:00
yanran200730
fd260eaefb Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2021-12-21 18:16:08 +08:00
yanran200730
6b1e4556d8 完成本村活动 2021-12-21 18:16:02 +08:00
aixianling
59c9757ca3 BUG 25629 2021-12-21 18:15:18 +08:00
aixianling
7a4fb1146e Merge remote-tracking branch 'origin/dev' into dev 2021-12-21 18:12:32 +08:00
aixianling
19e26af1a4 BUG 25628 2021-12-21 18:12:18 +08:00
yanran200730
c760419680 村民统计 2021-12-21 18:09:28 +08:00
yanran200730
0575dcadda Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2021-12-21 17:53:44 +08:00
yanran200730
ed55273d5a 居民活动统计页面 2021-12-21 17:53:38 +08:00
aixianling
7c3f031e6e 雷雷要加搜索过滤 2021-12-21 17:02:25 +08:00
aixianling
c83712640a BUG 25578 2021-12-21 16:52:49 +08:00
yanran200730
2526a22e38 招工就业 2021-12-21 16:51:36 +08:00
yanran200730
0dc777d02b 招工就业 2021-12-21 16:47:14 +08:00
yanran200730
47e0b485ab 内容发布 2021-12-21 15:31:55 +08:00
yanran200730
9dc6dbb4b7 内容发布 2021-12-21 14:40:05 +08:00
yanran200730
c32e22ac80 驻村辅警 2021-12-20 17:52:22 +08:00
yanran200730
931eca4fb3 驻村辅警 2021-12-20 17:50:06 +08:00
yanran200730
ae5cc0e0a4 内容管理 2021-12-20 17:31:30 +08:00
yanran200730
5fe29a09fb 乡村相册 2021-12-20 16:36:09 +08:00
yanran200730
354750e04a 乡村相册 2021-12-20 16:17:01 +08:00
yanran200730
b70dba7144 便民通讯录 2021-12-20 15:48:56 +08:00
yanran200730
b1e80ec0ca 本村活动 2021-12-20 15:33:16 +08:00
yanran200730
0b6c9ed68b 表单配置 2021-12-20 10:35:34 +08:00
yanran200730
2a88c51405 小程序公告 2021-12-20 10:25:02 +08:00
yanran200730
fe582353bb Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2021-12-20 09:35:46 +08:00
yanran200730
32dfdc495c 表单配置 2021-12-20 09:35:40 +08:00
aixianling
72e4300677 web端党史迁移完毕 2021-12-20 09:32:07 +08:00
aixianling
d21e874718 Merge remote-tracking branch 'origin/dev' into dev 2021-12-18 18:29:44 +08:00
aixianling
a0e5ca3656 迁移三会一课 2021-12-18 18:29:28 +08:00
yanran200730
63b12899f0 婚丧嫁娶 2021-12-18 17:50:37 +08:00
yanran200730
91c49e48d7 晒农产品 2021-12-18 17:42:41 +08:00
yanran200730
a2e9a4831a 晒农产品 2021-12-18 17:41:26 +08:00
yanran200730
238f9e5538 完成内容发布 2021-12-18 17:16:50 +08:00
aixianling
35a2b6f11d 释放管控逻辑 2021-12-18 17:03:13 +08:00
aixianling
947e07a1f3 Merge remote-tracking branch 'origin/dev' into dev 2021-12-18 16:47:56 +08:00
aixianling
5f0769868f 菜单优化 2021-12-18 16:47:40 +08:00
yanran200730
c3650e0b9c Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2021-12-18 14:16:57 +08:00
yanran200730
7527cdc8c2 本村活动 2021-12-18 14:16:50 +08:00
aixianling
9d8cd07b8a 调整样式 2021-12-18 11:45:22 +08:00
aixianling
dbf81a44e9 调整样式 2021-12-18 11:43:53 +08:00
aixianling
c30278f104 Merge remote-tracking branch 'origin/dev' into dev 2021-12-18 11:39:30 +08:00
aixianling
af0903a979 增加账号角色管理 2021-12-18 11:39:14 +08:00
yanran200730
3188da1ad3 本村活动 2021-12-18 11:27:59 +08:00
yanran200730
5134ae67f1 Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev 2021-12-18 10:29:55 +08:00
yanran200730
eb05a503ac 村民议事 2021-12-18 10:29:49 +08:00
aixianling
6f0f5d40b0 Merge remote-tracking branch 'origin/dev' into dev 2021-12-18 09:52:14 +08:00
aixianling
79b0a142cf 修改NPM脚本 2021-12-18 09:51:59 +08:00
yanran200730
6892ecf6df bug 2021-12-18 09:22:17 +08:00
aixianling
fc76fd16fc 增加系统信息管理在企微设置中 2021-12-17 15:10:38 +08:00
yanran200730
0cb223e80b bug 2021-12-17 09:51:09 +08:00
yanran200730
942a8c4106 完成村民活动 2021-12-16 19:10:31 +08:00
yanran200730
2e10daef30 完成本村相册 2021-12-16 18:10:43 +08:00
yanran200730
fee27b681b 完成本村辅警 2021-12-16 16:56:44 +08:00
yanran200730
9e7c39103f 本村简介,村规民约 2021-12-16 16:34:45 +08:00
yanran200730
7d15d4a1cb 完成本村简介和村规民约 2021-12-16 16:31:26 +08:00
yanran200730
3ce4c2f542 完成导航配置接口对接 2021-12-16 15:36:01 +08:00
yanran200730
f6ec0d0d96 小程序公告详情 2021-12-16 15:08:03 +08:00
yanran200730
0ed6cdb32e 完成小程序通告和便民通讯录 2021-12-16 15:04:47 +08:00
yanran200730
e39d41ec1a 导航配置 2021-12-16 14:17:10 +08:00
yanran200730
5464e830af 专题活动 2021-12-15 18:26:53 +08:00
yanran200730
e4af824c41 专题配置 2021-12-15 18:21:44 +08:00
yanran200730
af161676dd 婚丧嫁娶 2021-12-15 16:30:41 +08:00
yanran200730
62681fee0c 晒农产品 2021-12-15 15:43:33 +08:00
yanran200730
45ae210236 走访慰问 2021-12-15 15:13:28 +08:00
aixianling
0dbbbc40d3 调整自动路由 2021-12-14 18:54:03 +08:00
aixianling
a8dff862d2 初始化 2021-12-14 18:36:19 +08:00
736 changed files with 169022 additions and 3 deletions

31
.gitignore vendored Normal file
View File

@@ -0,0 +1,31 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
/package-lock.json
/lib
.prettierrc
/oms/dist/
/project/*/index.js
/project/*/dist

6
.npmrc Normal file
View File

@@ -0,0 +1,6 @@
registry=http://192.168.1.87:4873/
email=aixianling@sinoecare.com
always-auth=true
_auth="YWRtaW46YWRtaW4xMjM="
package-lock=false

View File

@@ -1,3 +0,0 @@
# dvcp_v2_webapp
村微2.0 前端应用库

5
core/.npmignore Normal file
View File

@@ -0,0 +1,5 @@
apps/
index.js
*.map
vcapps.import.js
dist/

View File

@@ -0,0 +1,288 @@
<template>
<section class="AppAccount">
<ai-list>
<ai-title slot="title" title="账号管理" isShowBottomBorder>
<template #rightBtn>
<el-button size="small" type="primary" icon="iconfont iconUpdate_Files" @click="syncDept">同步部门</el-button>
</template>
</ai-title>
<template #left>
<ai-address-book-menu :instance="instance" @select="handleSelect"/>
</template>
<template #content>
<ai-title :title="tableTitle"/>
<ai-search-bar>
<template #left>
<el-button type="primary" :disabled="!ids.toString()" @click="batchAllot">功能分配</el-button>
<el-button size="small" icon="iconfont iconUpdate_Files" @click="syncMembers">同步成员</el-button>
</template>
<template #right>
<el-input size="small" placeholder="搜索姓名、手机号" v-model="search.name" clearable
v-throttle="() => {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"
@selection-change="v=>ids=v.filter(e=>e.sysUserId).map(e=>e.sysUserId)">
<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="160px">
<el-row type="flex" justify="center" align="middle" slot-scope="{row}">
<el-button v-if="$permissions('admin_sysuser_distribute')&&!!row.sysUserId"
type="text" @click="appAllot(row)">功能分配
</el-button>
</el-row>
</el-table-column>
</ai-table>
</template>
</ai-list>
<!--功能分配-->
<ai-dialog title="功能分配" :visible.sync="dialog" width="800px" @open="initDialogData" @onConfirm="updateAccount">
<el-form ref="updateAccountForm" :model="dialogForm" :rules="rules" size="small"
label-width="120px">
<el-form-item required label="角色" prop="roleId">
<el-select size="small" 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 label="行政地区" prop="areaId">
<ai-area-select v-model="dialogForm.areaId" always-show :instance="instance"
clearable @fullname="v=>dialogForm.areaFullName=v"
@name="v=>dialogForm.areaName=v"
:disabledLevel="disabledLevel"/>
</el-form-item>
<el-form-item label="党组织" prop="organizationId" v-if="user.info.organizationId">
<el-cascader :options="partyOrgOps" v-model="dialogForm.organizationId"
:props="cascaderProps" :show-all-levels="false" clearable/>
</el-form-item>
<!-- <el-form-item label="职务" prop="position">-->
<!-- <el-input placeholder="请输入职务" v-model="dialogForm.position" clearable/>-->
<!-- </el-form-item>-->
</el-form>
</ai-dialog>
</section>
</template>
<script>
import {mapState} from "vuex";
import AiAddressBookMenu from "../../components/AiAddressBookMenu";
export default {
name: "AppAccount",
components: {AiAddressBookMenu},
label: "账号管理(村微版)",
props: {
instance: Function,
dict: Object,
permissions: Function
},
computed: {
...mapState(['user']),
cascaderProps() {
return {
value: 'id',
checkStrictly: true,
emitPath: false
}
},
partyOrgOps() {
let initData = JSON.parse(JSON.stringify(this.optionsParty)),
ops = initData.filter(e => !e.parentId)
ops.map(e => this.addChild(e, initData))
return ops
},
colConfigs() {
return [
{type: 'selection', align: 'center'},
{label: "姓名", slot: "name"},
{label: "职务", prop: "position", align: 'center', width: "120px"},
{label: "部门", prop: "departmentNames", align: 'center', width: "120px"},
{label: "联系方式", prop: "mobile", align: 'center', width: "120px"},
{label: "账号状态", prop: "status", dict: "wxUserStatus", width: "120px"},
{label: "账号角色", prop: "roleName", width: "120px", align: '120px'},
{label: "地区", prop: "areaName", width: "120px"},
{label: "党组织", prop: "organizationName", align: 'center', width: "120px"},
{slot: "options"}
]
},
tableTitle() {
return this.condition ? this.condition + `(${this.page.total})` : '请选择组织或标签'
},
rules() {
return {
name: [{required: true, message: "请填写姓名"}],
// organizationId: [{required: true, message: "请选择党组织"}],
// unitId: [{required: true, message: "请选择单位"}],
areaId: [{required: true, message: '请选择地区', trigger: 'change'}],
roleId: [{required: true, message: "请选择角色"}],
phone: [{required: true, message: "请输入手机号码"}]
}
},
disabledLevel() {
return this.user.info.areaList?.length || 0
}
},
data() {
return {
condition: "",
accountRoles: [],
page: {current: 1, size: 10, total: 0},
dialog: false,
dialogForm: {},
optionsParty: [],
tableData: [],
search: {name: ""},
ids: [],
lock: false
}
},
methods: {
getTableData() {
this.instance.post("/app/wxcp/wxuser/list", null, {
params: {...this.page, ...this.search}
}).then(res => {
if (res?.data) {
this.tableData = res.data?.records
this.page.total = res.data.total
}
})
},
handleSelect(v) {
if (v.type == 0) {
//选择部门
let {id: departmentId, name} = v
this.condition = name
this.search = {departmentId}
} else if (v.type == 1) {
//选择标签
let {id: tagIds, tagname: name} = v
this.condition = name
this.search = {tagIds}
}
this.page.current = 1
this.getTableData()
},
initDialogData() {
//用于优化初始化数据
this.getAccountRoles()
this.searchSysAll()
},
getAccountRoles() {
this.accountRoles.length == 0 && this.instance.post("/admin/role-acc/list-all").then(res => {
if (res?.data) {
this.accountRoles = res.data
}
})
},
batchAllot() {
this.dialog = true
this.dialogForm = {areaId: this.user.info.areaId, sysUserIds: this.ids}
},
appAllot(row) {
this.dialog = true
this.dialogForm = JSON.parse(JSON.stringify({
...row,
sysUserIds: [row.sysUserId],
areaId: row.areaId || this.user.info.areaId
}));
},
// 获取党组织树形
searchSysAll() {
if (this.user.info.organizationId && this.optionsParty.length == 0) {
this.instance.post('/app/partyOrganization/queryPartyOrganizationServiceList').then((res) => {
if (res?.data) {
res.data = res.data.map(a => {
return {...a, label: a.name}
});
this.optionsParty = res.data.filter(e => !e.parentId)
this.optionsParty.map(t => this.addChild(t, res.data));
}
})
}
},
// 修改
updateAccount() {
this.$refs.updateAccountForm.validate(v => {
if (v) {
if (this.lock) return this.$message.error("请勿多次提交!")
this.lock = true
this.instance.post("/app/wxcp/wxuser/empower", this.dialogForm).then(res => {
this.lock = false
if (res?.code == 0) {
this.dialog = false;
this.$message.success("修改成功")
this.getTableData();
} else {
this.$message.error(res?.msg)
}
}).catch(() => {
this.lock = false
})
}
})
},
syncMembers() {
const {departmentId = 1} = this.search;
let loading = this.$loading({
text: "正在同步成员...",
spinner: 'el-icon-loading',
background: "rgba(0,0,0,.8)"
})
this.instance.post(`/app/wxcp/wxdepartment/syncUser`, null, {
timeout: 1000000,
params: {departmentId}
}).then(res => {
if (res?.code == 0) {
this.$message.success('同步成功')
this.getList()
}
}).finally(() => loading.close())
},
syncDept() {
let loading = this.$loading({
text: "正在同步部门...",
spinner: 'el-icon-loading',
background: "rgba(0,0,0,.8)"
})
this.instance.post(`/app/wxcp/wxdepartment/syncDepart`).then(res => {
if (res?.code == 0) {
this.$message.success('同步成功')
this.getTree()
}
}).finally(() => loading.close())
}
},
created() {
this.dict.load('wxUserStatus')
}
}
</script>
<style lang="scss" scoped>
.AppAccount {
height: 100%;
::v-deep .avatar {
width: 40px;
height: 40px;
margin-right: 10px;
}
::v-deep .ai-list__content--left {
margin-right: 2px;
}
::v-deep .el-form {
.el-cascader {
width: 100%;
}
}
}
</style>

View File

@@ -0,0 +1,35 @@
<template>
<section class="AppAccountRole">
<add-account-role v-if="showDetail"/>
<account-role-list v-else/>
</section>
</template>
<script>
import AddAccountRole from "./addAccountRole";
import AccountRoleList from "./accountRoleList";
export default {
name: "AppAccountRole",
label: "账号角色管理",
props: {
instance: Function
},
components: {AccountRoleList, AddAccountRole},
computed: {
showDetail() {
return this.$route.hash == "#add"
}
},
provide() {
let {instance} = this
return {instance}
}
}
</script>
<style lang="scss" scoped>
.AppAccountRole {
height: 100%;
}
</style>

View File

@@ -0,0 +1,372 @@
<template>
<ai-list class="accountRoleList">
<ai-title slot="title" title="账号角色管理" isShowBottomBorder/>
<template #content>
<ai-search-bar>
<template #left>
<el-button
type="primary"
icon="el-icon-circle-plus"
@click="$router.push({hash:'#add'})"
v-if="$permissions('admin_sysaccountrole_add')"
>添加
</el-button>
<el-button
icon="el-icon-delete"
class="delete-btn del-btn-list"
@click="allDelete"
:disabled="!Boolean(multipleSelection.length)"
v-if="$permissions('admin_sysaccountrole_del')"
>删除
</el-button>
</template>
<template #right>
<el-input
size="small"
v-model="searchInfo"
placeholder="角色名称"
clearable
@keyup.enter.native="mhSearch()"
prefix-icon="iconfont iconSearch"
/>
<el-button
type="primary"
icon="iconfont iconSearch"
@click="mhSearch()"
>查询
</el-button
>
<el-button
icon="el-icon-refresh-right"
style="padding: 8px 13.5px"
@click="resetConditon"
>重置
</el-button
>
</template>
</ai-search-bar>
<el-table
:data="tableData"
@selection-change="handleSelectionChange"
header-cell-class-name="table-header"
tooltip-effect="light"
max-height="calc(100% - 80px)"
row-class-name="table-row"
cell-class-name="table-cell"
>
<el-table-column type="selection" width="55"/>
<el-table-column prop="name" label="角色名" width="300"/>
<el-table-column label="权限明细" prop="appRoleList">
<template slot-scope="scope">
<el-tooltip
content="更多角色用户请点击详情按钮"
placement="top"
effect="light"
v-if="scope.row.appRoleList.length > 3"
>
<span>{{ scope.row.appRoleListHtml }}</span>
</el-tooltip>
<span
v-for="(item, index) in scope.row.appRoleList"
:key="index"
v-else
>
<span>{{ item.appName }}-</span>
<span>{{ item.name }}</span>
</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" align="center">
<template class="operation_icon" slot-scope="scope">
<el-button
type="text"
size="small"
@click="beforeCopy(scope.row)"
v-if="$permissions('admin_sysaccountrole_add')"
>复制角色
</el-button>
<el-button
type="text"
size="small"
@click="detailShow(scope.row)"
v-if="$permissions('admin_sysaccountrole_detail')"
>详情
</el-button>
<el-button
type="text"
size="small"
@click="edit(scope.row)"
v-if="$permissions('admin_sysaccountrole_edit')"
>编辑
</el-button
>
<el-button
type="text"
size="small"
@click="beforeDelete(scope.row)"
v-if="$permissions('admin_sysaccountrole_del')"
>删除
</el-button
>
</template>
</el-table-column>
<div slot="empty" class="no-data"></div>
</el-table>
<div class="pagination">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
background
:page-size="pageSize"
:page-sizes="[10, 20, 50, 100, 200]"
layout="total,prev, pager, next,sizes, jumper"
:total="total"
/>
</div>
<el-dialog
class="editStyle"
:visible.sync="copyDialog"
width="520px"
@close="dataInit()"
title="复制角色"
>
<el-form :model="form" label-width="80px">
<el-form-item
label="角色名"
:rules="[{ required: true, message: '', trigger: 'blur' }]"
>
<el-input
v-model="roleName"
placeholder="请输入..."
size="small"
clearable
/>
</el-form-item>
</el-form>
<div slot="footer" style="text-align: center">
<el-button
style="width: 92px"
size="small"
class="delete-btn"
@click="copyDialog = false"
>取消
</el-button
>
<el-button
style="width: 92px"
size="small"
type="primary"
@click="copyFn()"
:disabled="!Boolean(roleName)"
>确认
</el-button>
</div>
</el-dialog>
<ai-dialog title="账号角色详情" :visible.sync="viewShow" customFooter>
<ai-card title="基本信息">
<template #content>
<ai-wrapper>
<ai-info-item label="账号角色名称" :value="row.name"/>
</ai-wrapper>
</template>
</ai-card>
<ai-card title="权限信息">
<template #content>
<div
class="view_info"
v-for="(item, index) in row.appRoleList"
:key="index"
>
<i class="iconfont iconProlife" style="color: #999"/>&nbsp;
{{ [item.appName, item.name].join(" / ") }}
</div>
</template>
</ai-card>
<template #footer>
<el-button
type="primary"
@click="edit(row)"
v-if="$permissions('admin_sysaccountrole_edit')"
>编辑角色
</el-button>
</template>
</ai-dialog>
</template>
</ai-list>
</template>
<script>
export default {
name: "accountRoleList",
inject:{
instance:{}
},
data() {
return {
searchInfo: "",
pageSize: 10,
tableData: [],
multipleSelection: [],
total: 0,
pageNum: 1,
row: {},
deleteIds: [],
copyDialog: false,
roleName: "",
viewShow: false,
titleDel: "",
form: {},
};
},
methods: {
getTableList() {
this.tableData = [];
this.instance.post(`/admin/role-acc/page`, null, {
params: {
pageSize: this.pageSize,
pageNum: this.pageNum,
roleName: this.searchInfo,
},
}).then((res) => {
if (res.code == 0) {
this.tableData = res.data.records;
this.total = res.data.total;
if (this.tableData.length) {
this.tableData.map((item) => {
if (item.appRoleList.length > 3) {
item.appRoleListHtml = `${item.appRoleList[0].appName}-${item.appRoleList[0].name}${item.appRoleList[1].appName}-${item.appRoleList[1].name}${item.appRoleList[2].appName}-${item.appRoleList[2].name}`;
}
});
}
}
});
},
dataInit() {
this.deleteIds = [];
this.multipleSelection = [];
this.row = {};
},
handleSelectionChange(val) {
this.deleteIds = [];
this.multipleSelection = val;
this.multipleSelection.forEach((e) => {
this.deleteIds.push(e.id);
});
},
allDelete() {
this.titleDel = "确定要执行删除操作吗?";
this.deleteRole();
},
beforeDelete(row) {
this.deleteIds = [];
this.row = row;
this.titleDel = "确定需要删除该角色吗?";
this.deleteIds.push(row.id);
this.deleteRole();
},
beforeCopy(row) {
this.row = row;
this.copyDialog = true;
},
detailShow(row) {
this.row = row;
this.viewShow = true;
},
edit(row) {
this.$router.push({
hash: "#add",
query: {
info: row,
},
});
},
copyFn() {
let crr = [];
let appRoleList = this.row.appRoleList;
appRoleList.forEach((e) => {
crr.push(e.id);
});
this.instance.post(`/admin/role-acc/modify?appRoles=${crr}`, null, {
params: {
roleName: this.roleName,
},
})
.then((res) => {
if (res.code == 0) {
this.$message({message: "复制成功", type: "success"});
this.copyDialog = false;
this.pageNum = 1;
this.getTableList();
}
});
},
deleteRole() {
this.$confirm(this.titleDel, {
type: "error",
})
.then(() => {
this.instance
.post(`/admin/role-acc/del?ids=${this.deleteIds}`, null, {})
.then((res) => {
if (res.code == 0) {
this.$message.success("删掉角色成功");
this.getTableList();
}
});
})
.catch(() => {
});
},
mhSearch() {
this.pageNum = 1;
this.getTableList();
},
// 重置
resetConditon() {
this.pageNum = 1;
this.searchInfo = "";
this.getTableList();
},
handleSizeChange(val) {
this.pageSize = val;
this.getTableList();
},
handleCurrentChange(val) {
this.pageNum = val;
this.getTableList();
},
},
created() {
this.getTableList();
},
};
</script>
<style lang="scss" scoped>
.accountRoleList {
height: 100%;
::v-deep.ai-card {
box-shadow: none;
border: 1px solid #eee;
.aibar {
height: 40px;
background: #f3f6f9;
}
.ai-card__body {
padding: 0 16px;
}
}
.view_info {
color: #333;
padding-left: 20px;
margin-bottom: 10px;
.info-title {
margin-bottom: 10px;
}
}
}
</style>

View File

@@ -0,0 +1,170 @@
<template>
<section class="addAccountRole">
<ai-detail>
<ai-title slot="title" :title="pageTitle" isShowBottomBorder isShowBack @onBackClick="$router.push({})"/>
<template #content>
<ai-card title="基本信息">
<template #content>
<el-form size="small" label-width="120px">
<el-form-item required label="账号角色名称">
<el-input clearable v-model="roleName" placeholder="请输入..."/>
</el-form-item>
</el-form>
</template>
</ai-card>
<ai-card title="角色信息(必选)">
<template #content>
<el-form size="small" label-width="120px">
<el-form-item required label="角色列表">
<div class="roleList">
<p class="input">
<el-input placeholder="请输入..." size="small" v-model="filterText" suffix-icon="iconfont iconSearch">
</el-input>
<el-button icon="iconfont iconDelete" size="small" @click="filterText=''">清空</el-button>
</p>
<div class="tree_list">
<el-tree
class="filter-tree"
:data="roleList"
show-checkbox
:props="defaultProps"
default-expand-all
:check-strictly="true"
node-key="id"
:default-checked-keys="defaultId"
:filter-node-method="filterNode"
ref="tree">
</el-tree>
</div>
</div>
</el-form-item>
</el-form>
</template>
</ai-card>
</template>
<template #footer>
<el-button @click="toAppRole">取消</el-button>
<el-button type="primary" @click="confirm">保存</el-button>
</template>
</ai-detail>
</section>
</template>
<script>
export default {
name: "addAccountRole",
inject: {instance: {}},
data() {
return {
roleName: '',
id: '',
roleList: [],
searchVal: '',
defaultProps: {
children: 'roles',
label: 'name'
},
treeList: [],
defaultId: [],
filterText: ''
}
},
computed: {
isAdd() {
return !this.$route.query?.info?.id
},
pageTitle() {
return this.isAdd ? "新增账号角色" : "编辑账号角色"
}
},
watch: {
filterText(val) {
this.$refs.tree.filter(val);
}
},
created() {
this.getAppList();
if (JSON.stringify(this.$route.query) != '{}') {
this.roleName = this.$route.query.info.name;
this.id = this.$route.query.info.id;
this.$route.query.info.appRoleList.forEach(e => {
this.defaultId.push(e.id)
})
}
},
methods: {
//查询下拉列表
getAppList() {
this.instance.post(`/admin/role-app/list-all`).then(res => {
if (res.code == 0) {
this.roleList = res.data;
this.roleList.forEach(e => {
e.disabled = true;
})
}
})
},
filterNode(value, data) {
if (!value) return true;
return data.name.indexOf(value) !== -1;
},
confirm() {
let crr = [];
let arrCheckList = [];
arrCheckList = this.$refs.tree.getCheckedKeys();
for (let i = 0; i < arrCheckList.length; i++) {
crr.push(arrCheckList[i]);
}
if (!this.roleName) {
this.$message.error('请输入账号角色名称')
return;
}
if (crr.length == 0) {
this.$message.error('请选择角色列表')
return;
}
this.instance.post(`/admin/role-acc/modify?appRoles=${crr}`, null, {
params: {
roleName: this.roleName,
id: this.id
}
}).then(res => {
if (res?.code == 0) {
this.$message({message: '保存成功', type: 'success'});
this.toAppRole()
}
})
},
//取消 返回
toAppRole() {
this.$router.push({})
}
}
}
</script>
<style lang="scss" scoped>
.addAccountRole {
height: 100%;
.roleList {
display: inline-block;
width: 340px;
height: 420px;
background-color: #fcfcfc;
border-radius: 2px;
border: solid 1px #d0d4dc;
.input {
display: flex;
justify-content: space-between;
padding: 5px;
margin: 0;
}
.tree_list {
height: 370px;
overflow: auto;
}
}
}
</style>

View File

@@ -0,0 +1,156 @@
<template>
<section class="AppDictionary">
<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>
</template>
<script>
import DictDetail from "./dictDetail";
export default {
name: "AppDictionary",
components: {DictDetail},
label: "数据字典",
props: {
instance: Function,
permissions: Function
},
computed: {
showDetail() {
return this.$route.hash == "#add"
}
},
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>
<style lang="scss" scoped>
.AppDictionary {
height: 100%;
}
</style>

View File

@@ -0,0 +1,202 @@
<template>
<section class="dictDetail">
<ai-detail>
<ai-title slot="title" title="字典信息" isShowBottomBorder isShowBack @onBackClick="$router.push({})"/>
<template #content>
<ai-card title="基本信息">
<template #content>
<el-form ref="dictDetailForm" :model="form" :rules="rules" size="small" label-width="110px">
<el-form-item required label="数据项:" prop="code">
<el-input v-model="form.code" style="width: 259px;" clearable
placeholder="请输入..."/>
</el-form-item>
<el-form-item required label="数据项名称:" prop="name">
<el-input v-model="form.name" style="width: 259px;" clearable
placeholder="请输入..."/>
</el-form-item>
</el-form>
</template>
</ai-card>
<ai-card title="数据值" v-if="$route.query.id">
<template #right>
<el-button type="text" icon="iconfont iconAdd"
@click="form.dictionaryDetails.push({name:'',value:'',editable:true})"> 添加
</el-button>
</template>
<template #content>
<el-table border :data="form.dictionaryDetails" header-cell-class-name="table-header"
cell-class-name="table-cell">
<el-table-column align="center" label="值">
<div slot-scope="{row}">
<el-input size="small" v-if="row.editable" v-model="row.value" clearable/>
<span v-else>{{ row.dictValue }}</span>
</div>
</el-table-column>
<el-table-column align="center" label="描述">
<div slot-scope="{row}">
<el-input size="small" v-if="row.editable" v-model="row.name" clearable/>
<span v-else>{{ row.dictName }}</span>
</div>
</el-table-column>
<el-table-column align="center" label="颜色">
<div slot-scope="{row}">
<el-color-picker v-if="row.editable" v-model="row.dictColor" size="medium"></el-color-picker>
<span v-else>{{ row.dictColor || '未设置' }}</span>
</div>
</el-table-column>
<el-table-column align="center" label="操作" width="109px">
<div slot-scope="{row,$index}">
<section v-if="row.editable">
<el-button style="color: #2EA222" type="text" icon="iconfont iconCorrect"
@click="addDict(row)"/>
<el-button style="color: #f46" type="text" icon="iconfont iconClean"
@click="cancelEdit(row,$index)"/>
</section>
<section v-else>
<el-button class="dict-detail-operation" type="text" icon="iconfont iconEdit"
@click="editDetail(row)"/>
<el-button class="dict-detail-operation" type="text" icon="iconfont iconDelete"
@click="delDictValue(row.id)"/>
</section>
</div>
</el-table-column>
</el-table>
</template>
</ai-card>
</template>
<template #footer>
<el-button @click="$router.push({})">返回</el-button>
<el-button type="primary" @click="modifyDict">保存</el-button>
</template>
</ai-detail>
</section>
</template>
<script>
export default {
name: "dictDetail",
props: {
instance: Function,
permissions: Function
},
computed: {
rules() {
return {
code: [
{required: true, message: "请填写数据项"}
],
name: [
{required: true, message: "请填写数据项名称"}
],
// dictionaryDetails: [
// {
// validator: (r, v, cb) => {
// if (v.every(item => item.dictName && item.dictValue)) {
// cb()
// }
// }
// }
// ]
}
}
},
data() {
return {
form: {
code: "",
name: "",
dictionaryDetails: []
},
}
},
created() {
if (this.$route.query.id) this.getDict()
},
methods: {
getDict() {
this.instance.post("/admin/dictionary/queryDictDetail", null, {
params: {dictionaryId: this.$route.query.id}
}).then(res => {
if (res?.data) {
res.data.dictionaryDetails = res.data.dictionaryDetails.map(d => {
return {
...d,
editable: false,
name: "",
value: ""
}
})
this.form = res.data
}
})
},
delDictValue(id) {
this.$confirm("是否要删除该字典值", {
type: 'error'
}).then(() => {
this.instance.post("/admin/dictionary/deletevalue", null, {
params: {id}
}).then(res => {
if (res?.code == 0) {
this.$message.success("删除成功!")
this.getDict()
}
})
}).catch(() => 0)
},
editDetail(row) {
row.editable = true
row.name = row.dictName
row.value = row.dictValue
},
addDict(row) {
row.dictValue = row.value
row.dictName = row.name
row.dictionaryId = this.form.id
this.instance.post("/admin/dictionary/updateDetail", row).then(res => {
row.editable = false
row = res.data.data
this.$message.success("提交成功!")
})
},
cancelEdit(row, index) {
if (row.id) {
row.editable = false
} else {
this.form.dictionaryDetails.splice(index, 1)
}
},
modifyDict() {
this.$refs.dictDetailForm.validate(v => {
if (v) {
this.instance.post("/admin/dictionary/updateDict", this.form).then(res => {
if (res?.code == 0) {
this.$message.success("提交成功!")
this.$router.push({})
}
})
}
})
}
}
}
</script>
<style lang="scss" scoped>
.dictDetail {
height: 100%;
::v-deep .el-table__row {
.el-input__inner {
padding: 0 30px;
border: none;
text-align: center;
background: #ddd;
font-size: 14px;
}
}
}
</style>

View File

@@ -0,0 +1,35 @@
<template>
<section class="AppMenuManager">
<component :is="currentPage" v-bind="$props"/>
</section>
</template>
<script>
import List from "./list";
import IntroPage from "./introPage";
export default {
name: "AppMenuManager",
components: {IntroPage, List},
label: "菜单管理",
props: {
instance: Function,
dict: {default: () => ({})}
},
computed: {
currentPage() {
const {hash} = this.$route
return hash == "#intro" ? IntroPage : List
}
},
created() {
this.dict.load("menuType", "yesOrNo")
}
}
</script>
<style lang="scss" scoped>
.AppMenuManager {
height: 100%;
}
</style>

View File

@@ -0,0 +1,96 @@
<template>
<section class="introPage">
<ai-detail :list="!edit">
<ai-title slot="title" title="引导页配置" isShowBottomBorder isShowBack @onBackClick="$router.push({})">
<template #rightBtn>
<ai-edit-btn @edit="edit=true,getConfigs()" @cancel="edit=false" @submit="submit"/>
</template>
</ai-title>
<template #content>
<el-form v-if="edit" :model="form" ref="IntroForm" size="small" :rules="rules" label-width="120px">
<ai-card title="基本信息">
<template #content>
<el-form-item label="副标题" prop="subtitle">
<el-input v-model="form.subtitle" clearable placeholder="请输入"/>
</el-form-item>
<el-form-item label="操作示例链接" prop="operationExamples">
<el-input v-model="form.operationExamples" clearable placeholder="请输入"/>
</el-form-item>
</template>
</ai-card>
<ai-card title="引导内容">
<template #content>
<el-form-item label-width="0" prop="guideContent">
<ai-editor :instance="instance" v-model="form.guideContent" placeholder="请输入" action="/oms/api/file/add" :params="{withoutToken:true}"/>
</el-form-item>
</template>
</ai-card>
</el-form>
<ai-intro v-else :id="$route.query.id" v-bind="$props"/>
</template>
</ai-detail>
</section>
</template>
<script>
import AiEditBtn from "../../components/AiEditBtn";
export default {
name: "introPage",
components: {AiEditBtn},
props: {
instance: Function,
dict: {default: () => ({})}
},
data() {
return {
form: {},
rules: {
subtitle: {required: true, message: "请输入副标题"},
guideContent: {required: true, message: "请输入引导内容"},
},
edit: false
}
},
methods: {
getConfigs() {
const {id} = this.$route.query
this.instance.post("/admin/sysappguideconfig/queryDetailById", null, {
params: {id}
}).then(res => {
if (res?.data) {
this.form = res.data
}
})
},
submit(cb) {
this.$refs.IntroForm.validate(v => {
if (v) {
const {form, $route: {query: {id}}} = this
this.instance.post("/admin/sysappguideconfig/addOrUpdate", {...form, id}).then(res => {
if (res?.code == 0) {
this.$message.success("提交成功!")
cb()
this.edit = false
}
})
}
})
}
}
}
</script>
<style lang="scss" scoped>
.introPage {
height: 100%;
::v-deep.ai-detail__content--wrapper {
min-height: 100%;
&.list {
padding-top: 0;
}
}
}
</style>

View File

@@ -0,0 +1,268 @@
<template>
<section class="list">
<ai-list>
<ai-title slot="title" title="菜单配置" isShowBottomBorder/>
<template #content>
<ai-search-bar>
<template #left>
<el-button type="primary" icon="el-icon-circle-plus" @click="addRootMenu">添加一级目录</el-button>
</template>
<template #right>
<el-input size="small" v-model="search" clearable @change="$refs.MenuTree.filter(search)"
placeholder="菜单名称"/>
<el-button icon="iconfont iconResetting" @click="getData">刷新</el-button>
</template>
</ai-search-bar>
<el-row type="flex" class="headerRow">
<div class="menuName" v-text="`菜单名称`"/>
<el-row type="flex" align="middle" class="info">
<div class="style" v-text="`图标`"/>
<div class="type" v-text="`菜单类型`"/>
<div class="component" v-text="`应用模块`"/>
<div class="status" v-text="`是否显示`"/>
<div class="showIndex" v-text="`排序`"/>
</el-row>
<div class="operation" v-text="`操作`"/>
</el-row>
<el-scrollbar>
<el-tree ref="MenuTree" :data="treeData" :props="{children:'subSet'}" highlight-current node-key="id"
:filter-node-method="handleSearch">
<el-row type="flex" align="middle" slot-scope="{node,data}" class="menuItem">
<div class="menuName" v-text="data.name"/>
<el-row type="flex" align="middle" class="info">
<div class="style" :class="data.style"/>
<div class="type" v-text="dict.getLabel('menuType',data.type)"/>
<div class="component" v-text="data.component"/>
<div class="status" v-text="dict.getLabel('yesOrNo',data.status)"/>
<div class="showIndex" v-text="data.showIndex"/>
</el-row>
<el-row type="flex" align="middle" class="operation">
<div v-if="node.isLeaf" class="opBtn del" v-text="`删除`" @click="handleDelete(data)"/>
<div v-if="data.component&&data.type==1" class="opBtn" v-text="`引导页`" @click="$router.push({hash:'#intro',query:{id:data.id}})"/>
<div v-if="data.type<2" class="opBtn" v-text="`添加下级`" @click="addMenu(data)"/>
<div class="opBtn" v-text="`编辑`" @click="handleEdit(data)"/>
</el-row>
</el-row>
</el-tree>
</el-scrollbar>
</template>
</ai-list>
<ai-dialog :visible.sync="dialog" title="菜单设置" width="500px" @onConfirm="handleSubmit"
@closed="form={},selected={}">
<el-form ref="MenuForm" :model="form" size="small" label-width="100px" :rules="rules">
<el-form-item label="菜单名称" prop="name">
<el-input v-model="form.name" placeholder="请输入" clearable/>
</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-input v-model="form.style" placeholder="请输入" clearable/>
</el-form-item>
</template>
<template v-if="form.type==1">
<el-form-item label="路由名" prop="route">
<span v-text="form.route||'提交保存后会自动生成'"/>
</el-form-item>
<el-form-item label="菜单应用" prop="component">
<el-input v-model="form.component" placeholder="请输入" clearable/>
</el-form-item>
<el-form-item label="路径(path)" prop="path">
<el-input v-model="form.path" placeholder="请输入" clearable/>
</el-form-item>
</template>
<template v-if="form.type==2">
<el-form-item label="权限码" prop="permission">
<el-input v-model="form.permission" placeholder="请输入" clearable/>
</el-form-item>
</template>
<el-form-item label="显示菜单" prop="status">
<ai-select v-model="form.status" clearable :selectList="dict.getDict('yesOrNo')"/>
</el-form-item>
<el-form-item v-if="form.type<2" label="排序" prop="showIndex">
<el-input v-model="form.showIndex" placeholder="请输入" clearable/>
</el-form-item>
</el-form>
</ai-dialog>
</section>
</template>
<script>
export default {
name: "list",
props: {
instance: Function,
dict: {default: () => ({})}
},
data() {
return {
treeData: [],
dialog: false,
form: {},
selected: {},
rules: {
name: [{required: true, message: "请输入 菜单名称"}],
type: [{required: true, message: "请选择 菜单类型"}],
status: [{required: true, message: "请选择 显示菜单"}],
showIndex: [{required: true, message: "请输入 排序"}],
permission: [{required: true, message: "请输入 权限码"}],
},
search: ""
}
},
methods: {
getData() {
return this.instance.post("/admin/menu/menuTree").then(res => {
if (res?.data) {
this.treeData = res.data
}
})
},
handleSubmit() {
this.$refs.MenuForm.validate(v => {
if (v) {
this.instance.post("/admin/menu/addOrUpdate", this.form).then(res => {
if (res?.code == 0) {
this.$message.success("提交成功!")
this.dialog = false
if (!!this.form.id) {
let node = this.$refs.MenuTree.getNode(this.form)
node.data = this.form
} else if (!!this.form.parentId) {
this.$refs.MenuTree.append(this.form, this.selected)
} else this.getData()
}
})
}
})
},
handleDelete(data) {
let {id} = data
this.$confirm("是否要删除该菜单").then(() => {
this.instance.post("/admin/menu/delete", null, {
params: {id}
}).then(res => {
if (res?.code == 0) {
this.$message.success("删除成功!")
this.dialog = false
this.$refs.MenuTree.remove(data)
}
})
}).catch(() => 0)
},
addRootMenu(row) {
this.dialog = true
this.selected = row
},
addMenu(row) {
this.dialog = true
this.form = {parentId: row.id}
this.selected = row
},
handleEdit(row) {
this.dialog = true
this.form = JSON.parse(JSON.stringify(row))
this.selected = row
},
handleSearch(value, data) {
if (!value) return true;
return data.name.indexOf(value) !== -1;
}
},
created() {
this.getData()
}
}
</script>
<style lang="scss" scoped>
.list {
height: 100%;
::v-deep .ai-list__content--right-wrapper {
height: calc(100% - 10px);
display: flex;
flex-direction: column;
.el-tree {
width: 100%;
height: 100%;
font-size: 14px;
.menuItem {
flex: 1;
min-width: 0;
}
.el-tree-node:nth-of-type(2n) {
background: rgba(#26f, .05);
}
.el-tree-node__content {
border-bottom: 1px solid #d0d4dc;
}
}
.el-scrollbar {
flex: 1;
min-height: 0;
.el-scrollbar__wrap {
overflow-x: auto;
}
}
.headerRow {
background: #f3f4f5;
color: #666;
font-weight: bold;
align-items: center;
height: 40px;
.menuName {
padding-left: 16px;
}
}
.info {
gap: 16px;
text-align: center;
.showIndex, .status, .type, .style {
width: 80px;
}
.component {
width: 300px;
}
}
.operation {
width: 300px;
flex-shrink: 0;
justify-content: flex-end;
text-align: center;
.opBtn {
cursor: pointer;
width: 60px;
font-size: 14px;
color: #26f;
&.del {
color: #f46;
}
}
}
.menuName {
flex: 1;
min-width: 0;
}
}
}
</style>

View File

@@ -0,0 +1,36 @@
<template>
<section class="AppQyWxConfig">
<component :is="currentPage" v-bind="$props"/>
</section>
</template>
<script>
import List from "./list";
import ThemeSetting from "./themeSetting";
export default {
name: "AppQyWxConfig",
components: {ThemeSetting, List},
label: "企业微信配置",
props: {
instance: Function,
dict: Object,
permissions: Function
},
computed: {
currentPage() {
const {hash} = this.$route
return hash == "#theme" ? ThemeSetting : List
}
},
created() {
this.dict.load("yesOrNo", "themeWeb", 'themeMp', "themeWxwork")
}
}
</script>
<style lang="scss" scoped>
.AppQyWxConfig {
height: 100%;
}
</style>

View File

@@ -0,0 +1,74 @@
<template>
<section class="AiSelectCard" flex>
<div class="checkCard" v-for="op in list" :key="op[props.value]" :class="{checked:op.dictValue==value}">
<el-image :src="op.thumb"/>
<el-row type="flex" class="bottomPane">
<b class="label fill" v-text="op[props.label]"/>
<el-button type="text" @click.stop="$emit('change',op[props.value])">使用</el-button>
</el-row>
</div>
</section>
</template>
<script>
export default {
name: "AiSelectCard",
model: {
prop: "value",
event: "change"
},
props: {
value: {default: ""},
ops: {default: () => []},
type: {default: "web"},
dict: String,
prop: {default: () => ({})}
},
computed: {
list: v => (v.dict ? v.$dict.getDict(v.dict) : v.ops || []).map(e => ({
...e,
thumb: `https://cdn.cunwuyun.cn/theme/thumb/${v.type}_${e[v.props.value]}.png`
})),
props: v => ({value: 'dictValue', label: 'dictName', ...v.prop})
}
}
</script>
<style lang="scss" scoped>
.AiSelectCard {
display: flex;
flex-wrap: wrap;
gap: 16px;
.checkCard {
width: 360px;
background: #fff;
border-radius: 8px;
overflow: hidden;
position: relative;
.label {
user-select: none;
}
&.checked:before {
position: absolute;
content: "应用中";
top: 16px;
left: 16px;
z-index: 9;
padding: 8px 16px;
background: rgba(#000, .7);
color: #fff;
border-radius: 8px;
}
.bottomPane {
height: 48px;
align-items: center;
padding: 0 16px;
border-top: 1px solid #eee;
}
}
}
</style>

View File

@@ -0,0 +1,485 @@
<template>
<section class="list">
<ai-list>
<ai-title slot="title" title="企业微信配置" isShowBottomBorder/>
<template #content>
<ai-search-bar>
<template #left>
<el-button type="primary" @click="add" icon="iconfont iconAdd">新增</el-button>
</template>
<template #right>
<el-input size="small" placeholder="搜索名称" v-model="search.name" clearable
@clear="page.current = 1,search.name = '', getTableData()"
v-throttle="() => {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">
<el-table-column type="expand" slot="expand">
<template slot-scope="{row}">
<ai-wrapper>
<ai-info-item labelWidth="200px" v-for="op in desConfigs" :key="op.prop" :value="row[op.prop]"
v-bind="op"/>
</ai-wrapper>
</template>
</el-table-column>
<el-table-column slot="status" align="center" label="状态" width="150">
<template v-slot="{ row }">
<el-switch v-model="row.status" @change="onChange(row)" active-value="1" inactive-value="0"
active-color="#5088FF" inactive-color="#D0D4DC"></el-switch>
</template>
</el-table-column>
<el-table-column slot="miniappStatus" align="center" label="小程序状态" width="150">
<template v-slot="{ row }">
<el-switch v-model="row.miniappStatus" @change="onMiniappStatusChange(row)" active-value="1"
inactive-value="0"
active-color="#5088FF" inactive-color="#D0D4DC"></el-switch>
</template>
</el-table-column>
<el-table-column slot="options" align="center" label="操作" width="400">
<el-row type="flex" justify="center" align="middle" slot-scope="{row}">
<el-button type="text" @click="detail(row)">详情</el-button>
<el-button type="text" @click="del(row)">删除</el-button>
<el-button type="text" @click="handleSystemInfo(row.id)">系统信息</el-button>
<el-button type="text" @click="handlePush(row.id)">推送随手拍样式</el-button>
<el-button type="text" @click="handleTheme(row.id)">主题样式</el-button>
</el-row>
</el-table-column>
</ai-table>
</template>
</ai-list>
<ai-dialog title="新增" :visible.sync="dialog" width="800px" @onConfirm="confirm">
<el-form ref="form" :model="dialogForm" :rules="rules" size="small" label-width="180px">
<el-form-item required label="名称" prop="name">
<el-input v-model.trim="dialogForm.name" placeholder="请输入名称" show-word-limit maxlength="100"></el-input>
</el-form-item>
<el-form-item label="企业微信ID" prop="corpId">
<el-input v-model.trim="dialogForm.corpId" placeholder="请输入企业微信ID" show-word-limit maxlength="32"></el-input>
</el-form-item>
<el-form-item label="企业微信通讯录SECRET" prop="corpAddressBookSecret">
<el-input v-model.trim="dialogForm.corpAddressBookSecret" placeholder="请输入企业微信通讯录SECRET" show-word-limit
maxlength="64"></el-input>
</el-form-item>
<el-form-item label="企业微信AESKEY" prop="corpAeskey">
<el-input v-model.trim="dialogForm.corpAeskey" placeholder="请输入企业微信AESKEY" show-word-limit
maxlength="64"></el-input>
</el-form-item>
<el-form-item label="企业微信AGENTID" prop="corpAgentId">
<el-input v-model.trim="dialogForm.corpAgentId" placeholder="请输入企业微信AGENTID" show-word-limit
maxlength="100"></el-input>
</el-form-item>
<el-form-item label="随手拍AGENTID" prop="clapAgentId">
<el-input v-model.trim="dialogForm.clapAgentId" placeholder="请输入随手拍AGENTID" show-word-limit
maxlength="100"></el-input>
</el-form-item>
<el-form-item label="企业微信SECRET" prop="corpSecret">
<el-input v-model.trim="dialogForm.corpSecret" placeholder="请输入企业微信SECRET" show-word-limit
maxlength="255"></el-input>
</el-form-item>
<el-form-item label="企业微信TOKEN" prop="corpToken">
<el-input v-model.trim="dialogForm.corpToken" placeholder="请输入企业微信TOKEN" show-word-limit
maxlength="32"></el-input>
</el-form-item>
<el-form-item label="小程序APPID" prop="miniappAppid">
<el-input v-model.trim="dialogForm.miniappAppid" placeholder="请输入小程序APPID" show-word-limit
maxlength="32"></el-input>
</el-form-item>
<el-form-item label="小程序SECRET" prop="miniappSecret">
<el-input v-model.trim="dialogForm.miniappSecret" placeholder="请输入小程序SECRET" show-word-limit
maxlength="32"></el-input>
</el-form-item>
<el-form-item label="企微访问域名" prop="dvcpUrl">
<el-input v-model.trim="dialogForm.dvcpUrl" placeholder="请输入企微访问域名" show-word-limit maxlength="128">
<template slot="prepend">Http://</template>
</el-input>
</el-form-item>
<el-form-item label="web访问域名" prop="webUrl">
<el-input v-model.trim="dialogForm.webUrl" placeholder="请输入web访问域名" show-word-limit maxlength="128">
<template slot="prepend">Http://</template>
</el-input>
</el-form-item>
<el-form-item label="地区" prop="areaId">
<ai-area-select :instance="instance" v-model="dialogForm.areaId" alwaysShow
@name="(e)=>dialogForm.areaName=e"/>
</el-form-item>
<el-form-item label="地图中心点" prop="lat">
<el-button type="primary" icon="iconfont iconAdd" @click="showMap=true">设置地点</el-button>
<div v-if="dialogForm.lat">{{ dialogForm.address }}</div>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model.trim="dialogForm.status">
<el-radio label="1">启用</el-radio>
<el-radio label="0">禁用</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="小程序状态" prop="miniappStatus">
<el-radio-group v-model.trim="dialogForm.miniappStatus">
<el-radio label="1">启用</el-radio>
<el-radio label="0">禁用</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="系统配置信息" prop="systemInfo">
<el-input type="textarea" :rows="2" placeholder="请输入系统配置信息" v-model="dialogForm.systemInfo"
maxlength="50000"/>
</el-form-item>
</el-form>
</ai-dialog>
<ai-dialog title="地图" :visible.sync="showMap" @opened="initMap" width="800px" class="mapDialog"
@onConfirm="selectMap">
<div id="map"></div>
<el-input id="searchPlaceInput" size="medium" class="searchPlaceInput" clearable v-model="searchPlace"
autocomplete="on"
@change="placeSearch.search(searchPlace)">
<el-button type="primary" slot="append" @click="placeSearch.search(searchPlace)">搜索</el-button>
</el-input>
<div id="searchPlaceOutput"/>
</ai-dialog>
<ai-dialog title="系统信息设置" :visible.sync="sysInfoDialog" width="600px" @onConfirm="submitSystemInfo"
@closed="sysInfo={}">
<el-form size="small" label-width="140px">
<el-form-item label="页签标题">
<el-input v-model="sysInfo.title" placeholder="请输入..." clearable/>
</el-form-item>
<el-form-item label="系统标题">
<el-input v-model="sysInfo.fullTitle" placeholder="请输入..." clearable/>
</el-form-item>
<el-form-item label="logo">
<el-input v-model="sysInfo.logo" placeholder="请输入..." clearable/>
</el-form-item>
<el-form-item label="登录页左上角标题">
<el-input v-model="sysInfo.name" placeholder="请输入..." clearable/>
</el-form-item>
<el-form-item label="登录页副标题">
<el-input type="textarea" rows="5" v-model="sysInfo.desc" placeholder="请输入..." clearable/>
</el-form-item>
<el-form-item label="版权所有">
<el-input v-model="sysInfo.recordDesc" placeholder="请输入..." clearable/>
</el-form-item>
<el-form-item label="备案号">
<el-input v-model="sysInfo.recordNo" placeholder="请输入..." clearable/>
</el-form-item>
<el-form-item label="备案跳转链接">
<el-input v-model="sysInfo.recordURL" placeholder="请输入..." clearable/>
</el-form-item>
<el-form-item label="框架版本">
<!--edition 版本标准版standard上架版saas-->
<el-input v-model="sysInfo.edition" placeholder="请输入..." clearable/>
</el-form-item>
</el-form>
</ai-dialog>
</section>
</template>
<script>
import {mapState} from "vuex";
import AMapLoader from "@amap/amap-jsapi-loader"
export default {
name: "list",
props: {
instance: Function,
dict: Object,
permissions: Function
},
computed: {
...mapState(['user']),
colConfigs() {
return [
{slot: 'expand'},
{prop: "name", label: "名称"},
{prop: "corpId", label: "企业微信ID", width: 180},
{slot: "status",},
{slot: "miniappStatus"},
{prop: "createTime", label: "创建时间"},
{slot: "options"},
]
},
desConfigs() {
let isLine = true
return [
{prop: "corpAddressBookSecret", label: "企业微信通讯录SECRET", width: 200},
{prop: "corpAgentId", label: "企业微信AGENTID", width: 150},
{prop: "corpSecret", label: "企业微信SECRET", isLine},
{prop: "corpToken", label: "企业微信TOKEN", width: 150},
{prop: "corpAeskey", label: "企业微信AESKEY", width: 150},
{prop: "miniappAppid", label: "小程序APPID", width: 150},
{prop: "miniappSecret", label: "小程序SECRET", width: 150},
{prop: "areaId", label: "地区编码", width: 150, isLine},
{prop: "lat", label: "纬度", width: 100},
{prop: "lng", label: "经度", width: 100},
{prop: "address", label: "中心点", width: 100, isLine},
{prop: "webUrl", label: "管理端地址", width: 100},
{prop: "dvcpUrl", label: "企微端地址", width: 100},
]
},
rules() {
return {
name: [{required: true, message: "请填写名称"}],
corpId: [{required: true, message: "请填写企业微信ID"}],
corpAddressBookSecret: [{required: true, message: "请填写企业微信通讯录SECRET"}],
corpAeskey: [{required: true, message: "请填写企业微信AESKEY"}],
corpAgentId: [{required: true, message: "请填写企业微信AGENTID"}],
corpSecret: [{required: true, message: "请填写企业微信SECRET"}],
corpToken: [{required: true, message: "请填写企业微信TOKEN"}],
miniappAppid: [{required: true, message: "请填写小程序APPID"}],
miniappSecret: [{required: true, message: "请填写小程序SECRET"}],
dvcpUrl: [{required: true, message: "请填写企微访问域名"}],
webUrl: [{required: true, message: "请填写web访问域名"}],
status: [{required: true, message: "请选择状态", trigger: "change"}],
miniappStatus: [{required: true, message: "请选择小程序状态", trigger: "change"}],
areaId: [{required: true, message: "请选择地区", trigger: "change"}],
lat: [{required: true, message: "请选择中心点"}],
systemInfo: [{required: true, message: "请输入系统配置信息"}],
}
},
},
data() {
return {
page: {current: 1, size: 10, total: 0},
dialog: false,
showMap: false,
map: null,
placeSearch: null,
placeDetail: {},
searchPlace: "",
dialogForm: {},
tableData: [],
search: {
name: ""
},
sysInfo: {},
sysInfoDialog: false
}
},
methods: {
selectMap() {
Object.keys(this.placeDetail).map(e => this.dialogForm[e] = this.placeDetail[e]);
this.showMap = false;
},
initMap() {
AMapLoader.load({
key: 'b553334ba34f7ac3cd09df9bc8b539dc',
version: '2.0',
plugins: ['AMap.PlaceSearch', 'AMap.AutoComplete', 'AMap.Geocoder'],
}).then(AMap => {
this.map = new AMap.Map('map', {
resizeEnable: true,
zooms: [6, 20],
center: [116.394681, 39.910283],
zoom: 11
})
this.placeSearch = new AMap.PlaceSearch({map: this.map})
new AMap.AutoComplete({
input: "searchPlaceInput",
output: 'searchPlaceOutput',
}).on('select', e => {
if (e?.poi) {
this.placeSearch.setCity(e.poi.adcode);
this.movePosition(e.poi.location)
}
})
this.map.on('click', e => {
new AMap.Geocoder().getAddress(e.lnglat, (sta, res) => {
if (res?.regeocode) {
this.placeDetail = {
lng: e.lnglat?.lng,
lat: e.lnglat?.lat,
address: res.regeocode.formattedAddress
}
}
})
this.movePosition(e.lnglat)
})
})
},
movePosition(center) {
if (this.map) {
this.map.clearMap()
this.map.panTo(center)
this.map.add([
new AMap.Marker({
position: center,
clickable: true
})
])
this.map.setFitView()
}
},
onChange(row) {
this.instance.post(`/app/appdvcpconfig/setStatus`, null, {
params: {
id: row.id,
status: row.status
}
}).then((res) => {
if (res.code == 0) {
this.$message.success(+row.status ? '已启用' : '已禁用');
this.getTableData();
}
})
},
onMiniappStatusChange(row) {
this.instance.post(`/app/appdvcpconfig/setMiniappStatus`, null, {
params: {
id: row.id,
status: row.miniappStatus
}
}).then((res) => {
if (res.code == 0) {
this.$message.success(+row.miniappStatus ? '已启用' : '已禁用');
this.getTableData();
}
})
},
add() {
this.dialogForm = {};
this.dialog = true;
},
del(row) {
this.$confirm("是否要删除?").then(_ => {
this.instance.post("/app/appdvcpconfig/delete", null, {
params: {
ids: row.id
}
}).then(res => {
if (res.code == 0) {
this.$message.success("删除成功");
this.dialog = false;
this.getTableData();
}
})
})
},
detail(row) {
this.instance.post("/app/appdvcpconfig/detail", null, {
params: {
id: row.id
}
}).then(res => {
if (res && res.data) {
this.dialogForm = {...res.data};
this.dialog = true;
}
})
},
getTableData() {
this.instance.post("/app/appdvcpconfig/list", null, {
params: {...this.page, ...this.search}
}).then(res => {
if (res?.data) {
this.tableData = res.data?.records
this.page.total = res.data.total
}
})
},
confirm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.instance.post("/app/appdvcpconfig/addOrUpdate", {
...this.dialogForm,
}).then(res => {
if (res.code == 0) {
this.$message.success(this.dialogForm.id ? "修改成功" : "新增成功");
this.dialog = false;
this.getTableData();
}
})
}
})
},
handleSystemInfo(id) {
this.sysInfoDialog = true
this.getSystemInfo(id)
},
getSystemInfo(id) {
this.instance.post("/app/appdvcpconfig/getSystemInfo", null, {
params: {id}
}).then(res => {
if (res?.data) {
this.sysInfo = JSON.parse(res.data)
this.sysInfo.id = id
}
})
},
submitSystemInfo() {
let {id} = this.sysInfo
this.instance.post("/app/appdvcpconfig/updateSystemInfo", this.sysInfo, {params: {id}}).then(res => {
if (res?.code == 0) {
this.$message.success("提交成功!")
this.sysInfoDialog = false
}
})
},
handlePush(id) {
this.instance.post("/app/appclapeventinfo/setAppWorkbench", null, {params: {id}}).then(res => {
if (res?.code == 0) {
this.$message.success("推送成功!")
}
})
},
handleTheme(id) {
this.$router.push({hash: "#theme", query: {id}})
}
},
created() {
this.getTableData()
}
}
</script>
<style lang="scss" scoped>
.list {
height: 100%;
::v-deep .mapDialog {
.el-dialog__body {
padding: 0;
.ai-dialog__content {
padding: 0;
}
.ai-dialog__content--wrapper {
padding: 0 !important;
position: relative;
}
#map {
width: 100%;
height: 500px;
}
.searchPlaceInput {
position: absolute;
width: 250px;
top: 30px;
left: 25px;
}
#searchPlaceOutput {
position: absolute;
width: 250px;
left: 25px;
height: initial;
top: 80px;
background: white;
z-index: 250;
max-height: 300px;
overflow-y: auto;
.auto-item {
text-align: left;
font-size: 14px;
padding: 8px;
box-sizing: border-box;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,83 @@
<template>
<section class="themeSetting">
<ai-detail list>
<ai-title slot="title" title="主题样式" isShowBottomBorder isShowBack @back="cancel">
<template #rightBtn>
<span class="mar-r8" v-text="'灰色滤镜'"/>
<el-switch size="mini" v-model="form.enableGreyFilter" name="灰色滤镜" border active-value="1" inactive-value="0"/>
</template>
</ai-title>
<template #content>
<el-form size="small" :model="form" ref="ThemeForm">
<ai-title title="WEB后台"/>
<ai-select-card dict="themeWeb" v-model="form.colorScheme.web"/>
</el-form>
</template>
<template #footer>
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="submit">提交</el-button>
</template>
</ai-detail>
</section>
</template>
<script>
import AiSelectCard from "./components/AiSelectCard";
export default {
name: "themeSetting",
components: {AiSelectCard},
props: {
instance: Function,
dict: Object,
permissions: Function
},
data() {
return {
form: {enableGreyFilter: '0', colorScheme: {}}
}
},
methods: {
getDetail() {
const {id} = this.$route.query
this.instance.post("/app/appdvcpconfig/detail", null, {params: {id}}).then(res => {
if (res?.data) {
let {colorScheme, enableGreyFilter} = res.data
colorScheme = JSON.parse(colorScheme) || {web: 'blue'}
this.form = {colorScheme, enableGreyFilter}
}
})
},
cancel() {
return this.$router.push({})
},
submit() {
this.$refs.ThemeForm.validate(v => {
if (v) {
let {colorScheme} = this.form
colorScheme = JSON.stringify(colorScheme)
this.instance.post("/app/appdvcpconfig/updateSysColorScheme", {...this.form, colorScheme}).then(res => {
if (res?.code == 0) {
this.$message.success("保存成功!")
this.cancel().then(() => location.reload())
}
})
}
})
}
},
created() {
this.getDetail()
}
}
</script>
<style lang="scss" scoped>
.themeSetting {
height: 100%;
.mar-r8 {
margin-right: 8px;
}
}
</style>

View File

@@ -0,0 +1,443 @@
<template>
<section class="AppRightsManager">
<ai-list v-if="!showDetail">
<ai-title slot="title" title="权限管理" isShowBottomBorder/>
<template #content>
<ai-search-bar>
<template #left>
<ai-select placeholder="请选择应用" v-model="search.appId" :selectList="appList"
@change="searchList"/>
</template>
<template #right>
<el-input
size="small"
v-model="search.roleName"
placeholder="角色名称"
clearable
@change="searchList()"
suffix-icon="iconfont iconSearch"/>
</template>
</ai-search-bar>
<ai-search-bar>
<template #left>
<el-button size="small" type="primary" icon="iconfont iconAdd"
@click="$router.push({hash:'#add'})"
v-if="$permissions('admin_sysapprole_add')">
添加
</el-button>
<el-button
size="small"
icon="iconfont iconDelete"
:disabled="!multipleSelection.length"
class="del-btn-list"
@click="deleteApp('all')"
v-if="$permissions('admin_sysapprole_del')"
>删除
</el-button>
</template>
</ai-search-bar>
<ai-table :tableData="adminList" :colConfigs="colConfigs" :total="total" :current.sync="page.pageNum"
:size.sync="page.pageSize"
@getList="getTableData" :col-configs="colConfigs" :dict="dict"
@selection-change="v=>multipleSelection=v">
<el-table-column label="角色用户" slot="users" align="center">
<template slot-scope="scope">
<el-tooltip
effect="light"
placement="top"
:disabled="scope.row.users.length <= 2"
content="更多角色用户请点击详情按钮">
<span v-if="scope.row.users.length">
{{
scope.row.users
.slice(0, 2)
.map((e) => e.name + "(" + e.phone + ")")
.join(";")
}}
<span v-if="scope.row.users.length > 2">...</span>
</span>
<span v-else>-</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column slot="options" label="操作" fixed="right" align="center">
<template slot-scope="{row}">
<el-button type="text" @click="beforeCopy(row)" v-if="$permissions('admin_sysapprole_edit')">复制
</el-button>
<el-button type="text" @click="viewApp(row)" v-if="$permissions('admin_sysapprole_detail')">详情
</el-button>
<el-button type="text" @click="openRightsGraph(row)" v-if="$permissions('admin_sysapprole_detail')">关系图
</el-button>
<el-button type="text" @click="toAddAppRole(row)" v-if="$permissions('admin_sysapprole_edit')">编辑
</el-button>
<el-button type="text" @click="deleteApp(row)" v-if="$permissions('admin_sysapprole_del')">删除</el-button>
</template>
</el-table-column>
</ai-table>
<ai-dialog
title="应用角色详情"
:visible.sync="viewShow"
width="600px"
customFooter>
<ai-card title="基本信息">
<template #content>
<ai-wrapper>
<ai-info-item label="应用角色名称" :value="viewInfo.name"/>
<ai-info-item label="应用名称" :value="viewInfo.appName"/>
</ai-wrapper>
</template>
</ai-card>
<ai-card title="权限信息">
<template #content>
<ai-wrapper>
<ai-info-item :label="viewInfo.appName" isLine>
{{ roleList.map(e => e.label).join('、') }}
</ai-info-item>
</ai-wrapper>
</template>
</ai-card>
<ai-card title="角色账号">
<template #right>
<span style="text-align: right; color: #999"
>共<span
style="color: #26f"
v-text="userList.length"
/>个账号</span
>
</template>
<template #content>
<div class="datail-table-body" v-if="userList.length">
<div class="datail-item" v-for="(item, index) in userList" :key="index">
<span class="item-name">{{ item.name }}</span>
<span style="color: #999">{{ item.phone }}</span>
</div>
</div>
</template>
</ai-card>
<template #footer>
<el-button
type="primary"
@click="toAddAppRole(viewInfo)"
v-if="$permissions('admin_sysapprole_edit')"
>编辑角色
</el-button>
</template>
</ai-dialog>
<ai-dialog title="权限关系图" :visible.sync="rightsGraph" class="rightsGraphDialog" customFooter>
<rights-graph :instance="instance" :dict="dict" :app="selectApp"/>
<el-button slot="footer" @click="rightsGraph=false">关闭</el-button>
</ai-dialog>
<!--复制角色-->
<el-dialog
class="editStyle"
:visible.sync="copyDialog"
width="520px"
@close="dataInit()"
title="复制角色">
<el-form :model="form" label-width="80px">
<el-form-item label="角色名" :rules="[{ required: true, message: '', trigger: 'blur' }]">
<el-input
v-model="editName"
placeholder="请输入..."
size="small"
clearable
/>
</el-form-item>
</el-form>
<div slot="footer" style="text-align: center">
<el-button
style="width: 92px"
size="small"
@click="copyDialog = false"
>取消
</el-button
>
<el-button
style="width: 92px"
size="small"
type="primary"
@click="copyFn()"
:disabled="!editName"
>
确认
</el-button>
</div>
</el-dialog>
</template>
</ai-list>
<rights-add v-else :instance="instance" :dict="dict" :permissions="permissions"/>
</section>
</template>
<script>
import RightsAdd from "./rightsAdd";
import RightsGraph from "./rightsGraph";
export default {
name: "AppRightsManager",
components: {RightsGraph, RightsAdd},
label: "权限管理",
provide() {
return {
top: this
}
},
props: {
instance: Function,
dict: Object,
permissions: Function,
actions: {
default: () => ({
list: '/admin/role-app/page',
apps: '/admin/role-app/list-all',
delete: '/admin/role-app/del',
detail: '/admin/role-app/queryById-checked',
modify: '/admin/role-app/modify',
})
}
},
computed: {
colConfigs() {
return [
{type: "selection"},
{label: "应用", prop: "appName", width: '120px'},
{label: "角色名", prop: "name", width: '100px'},
{label: "用户数量", prop: "roleCount", align: 'center', width: '80px'},
{slot: "users"},
{slot: "options"}
]
},
showDetail() {
return this.$route.hash == "#add"
}
},
data() {
return {
page: {pageNum: 1, pageSize: 10},
search: {appId: '', roleName: ''},
adminList: [], //列表数据
total: 0,
appList: [], //下拉选择列表
multipleSelection: [],
delShow: false,
delParams: "",
delIds: [],
viewShow: false,
viewInfo: {},
roleList: [], //详情权限列表
row: {},
copyDialog: false,
titleDel: "",
form: {},
editName: "",
userList: [],
rightsGraph: false,
selectApp: {}
};
},
created() {
this.getTableData();
this.getAppList();
},
methods: {
//查询table列表
getTableData() {
this.adminList = [];
this.instance.post(this.actions.list, null, {
params: {...this.page, ...this.search}
}).then(res => {
if (res?.data) {
this.total = res.data.total;
this.adminList = res.data.records;
}
})
},
//查询下拉列表
getAppList() {
this.instance.post(this.actions.apps).then(res => {
if (res?.data) {
this.appList = res.data?.map(e => ({dictName: e.name, dictValue: e.id}))
}
})
},
//查询
searchList() {
this.page.pageNum = 1;
this.getTableData();
},
//添加按钮
toAddAppRole(item) {
this.$router.push({
hash: "#add",
query: {
id: item.id,
name: item.name,
appId: item.appId,
},
});
},
//删除
deleteApp(e) {
if (e == "all") {
this.multipleSelection.map((item) => {
this.delIds.push(item.id);
});
this.delParams = `ids=${this.delIds}`;
this.titleDel = "确定要执行删除操作吗";
} else {
this.delParams = `ids=${e.id}`;
this.titleDel = "确定需要删除该角色吗";
}
this.$confirm(this.titleDel, {
type: "error",
}).then(() => {
this.instance.post(`${this.actions.delete}?${this.delParams}`).then(res => {
if (res?.msg == "success") {
this.getTableData();
} else {
this.$message.error(res.msg);
}
});
}).catch(() => 0);
},
//查看信息
viewApp(e) {
this.userList = e.users;
this.viewInfo = e;
this.viewShow = true;
this.getRowInfo(this.viewInfo.appId, this.viewInfo.id);
},
//查询 row 信息
getRowInfo(appId, id) {
this.roleList = [];
this.instance.post(`${this.actions.detail}?id=${appId}&roleId=${id}`)
.then(res => {
if (res?.data) {
this.roleList = res.data.list.filter(e => e.checked)
}
})
},
//复制
beforeCopy(row) {
this.row = row;
this.copyDialog = true;
this.getRowInfo(this.row.appId, this.row.id);
},
//确认复制
copyFn() {
let crr = [];
let appRoleList = this.roleList;
for (let i = 0; i < appRoleList.length; i++) {
if (appRoleList[i].checked) {
crr.push(appRoleList[i].id);
if (appRoleList[i].list.length) {
for (let j = 0; j < appRoleList[i].list.length; j++) {
if (appRoleList[i].list[j].checked) {
crr.push(appRoleList[i].list[j].id);
}
}
}
}
}
this.instance.post(`${this.actions.modify}?menus=${crr}`, null, {
params: {
roleName: this.editName,
appId: this.row.appId,
},
})
.then((res) => {
if (res.code == 0) {
this.$message({message: "复制成功", type: "success"});
this.copyDialog = false;
this.searchList()
}
});
},
dataInit() {
this.multipleSelection = [];
this.row = {};
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
openRightsGraph(row) {
this.rightsGraph = true
this.selectApp = row
}
},
}
</script>
<style lang="scss" scoped>
.AppRightsManager {
height: 100%;
::v-deep .ai-dialog {
.ai-card {
box-shadow: none;
border: 1px solid #eee;
.aibar {
height: 40px;
background: #f3f6f9;
}
.ai-card__body {
padding: 0 16px;
}
}
}
::v-deep .rightsGraphDialog {
.el-dialog__body {
padding: 0;
}
.ai-dialog__content {
padding-bottom: 0;
}
}
::v-deep .datail-table-body {
width: 100%;
height: auto;
margin-bottom: 16px;
display: flex;
flex-wrap: wrap;
.datail-item {
flex-shrink: 0;
width: 50%;
height: 24px;
line-height: 24px;
span {
display: inline-block;
font-size: 12px;
}
.item-name {
width: 102px;
padding-left: 16px;
color: #333;
}
}
.datail-item:nth-of-type(2n - 1) {
border-right: 1px solid rgba(208, 212, 220, 1);
width: calc(50% - 1px);
}
}
.padd-l0 {
padding-left: 0 !important;
}
.pad-l16 {
padding-left: 16px;
}
}
</style>

View File

@@ -0,0 +1,195 @@
<template>
<ai-detail class="rightsAdd">
<ai-title :title="addTitle" slot="title" isShowBottomBorder isShowBack @onBackClick="back"/>
<template #content>
<el-form size="small" ref="rightsForm" :model="form" label-width="120px" :rules="rules">
<ai-card title="基本信息">
<template #content>
<el-form-item label="应用角色名称" prop="roleName">
<el-input v-model="form.roleName" placeholder="请输入应用角色名称" clearable/>
</el-form-item>
</template>
</ai-card>
<ai-card title="权限信息">
<template #content>
<el-form-item label="应用" prop="appId">
<ai-select placeholder="请选择应用" v-model="form.appId" :selectList="top.appList"
@change="getPermissions"/>
</el-form-item>
<el-form-item label="权限列表" prop="menus" v-if="form.appId">
<div class="roleList">
<el-input v-model="filterText" placeholder="请输入..." clearable suffix-icon="iconfont iconSearch"
@change="$refs.tree.filter(filterText)" :validate-event="false"/>
<div class="tree_list">
<el-tree class="filter-tree" ref="roleTree"
:data="roleList"
show-checkbox
:props="defaultProps"
default-expand-all
:check-strictly="false"
node-key="id"
:default-checked-keys="form.menus"
:filter-node-method="filterNode"
@check="handleMenusSelect"/>
</div>
</div>
</el-form-item>
</template>
</ai-card>
</el-form>
</template>
<template #footer>
<el-button @click="back()">取消</el-button>
<el-button type="primary" @click="confirm">保存</el-button>
</template>
</ai-detail>
</template>
<script>
export default {
name: "rightsAdd",
inject: ['top'],
props: {
instance: Function,
dict: Object,
permissions: Function
},
data() {
return {
form: {},
roleName: '',
id: '',
appList: [],
roleList: [],
defaultProps: {
children: 'list',
label: 'name'
},
treeList: [],
filterText: '',
msgTitle: '添加',
}
},
created() {
if (this.isEdit) {
let {id, appId, name: roleName} = this.$route.query
this.form = {appId, menus: [], id, roleName}
this.getPermissions()
this.msgTitle = '编辑'
}
},
computed: {
isEdit() {
return this.$route.query.id
},
addTitle() {
return this.isEdit ? '编辑应用角色' : '新增应用角色'
},
rules() {
return {
roleName: {required: true, message: '请输入应用角色名称'},
appId: {required: true, message: '请选择应用'},
menus: {required: true, message: '请选择权限列表内容'},
}
}
},
methods: {
filterNode(value, data) {
if (!value) return true;
return data.name.indexOf(value) !== -1;
},
//应用名称选择 获取权限列表
getId(data) {
if (data.list.length) {
data.list.forEach(item => {
this.getId(item)
})
} else {
if (data.checked) {
this.form.menus?.push(data.id)
}
}
},
getPermissions() {
this.filterText = ''
let {appId: id, id: roleId} = this.form
this.instance.post(this.top.actions.detail, null, {
params: {id, roleId}
}).then(res => {
if (res?.data) {
this.roleList = [res.data];
if (this.isEdit) {
this.roleList.forEach(e => this.getId(e))
}
this.roleList = this.roleList.filter(item => !(item.component && item.isApp == 0 && item.isMenu == 0))
}
})
},
handleMenusSelect(node, selected) {
this.$set(this.form, 'menus', [...selected?.checkedKeys])
this.$refs.rightsForm.validateField('menus')
},
//保存提交
confirm() {
this.$refs.rightsForm.validate(v => {
if (v) {
let menus = [this.$refs.roleTree?.getHalfCheckedKeys(), this.$refs.roleTree?.getCheckedKeys()]?.flat()?.toString()
this.instance.post(this.top.actions.modify, null, {
params: {...this.form, menus}
}).then(res => {
if (res?.code == 0) {
this.$message.success(`${this.msgTitle}应用角色成功`)
this.back()
this.top.searchList()
}
})
}
})
},
//取消 返回
back() {
this.$router.push({})
}
}
}
</script>
<style lang="scss" scoped>
.rightsAdd {
width: 100%;
height: 100%;
position: relative;
.el-form-item {
.el-select {
width: 100%;
}
&.is-error {
.roleList {
border-color: #f46;
}
}
}
.roleList {
background-color: #fcfcfc;
border-radius: 2px;
border: solid 1px #d0d4dc;
padding: 8px;
.input {
display: flex;
justify-content: space-between;
padding: 5px;
margin: 0;
}
.tree_list {
padding: 5px;
height: 370px;
overflow: auto;
}
}
}
</style>

View File

@@ -0,0 +1,192 @@
<template>
<section class="rightsGraph">
<div id="RightGraph"/>
</section>
</template>
<script>
import * as echarts from "echarts";
export default {
name: "rightsGraph",
inject: ['top'],
props: {
instance: Function,
dict: Object,
app: Object
},
computed: {
graphData() {
let data = [...this.users, ...this.nodes].map(e => {
if (e.x) {
return e
} else return {...e, ...this.renderPosition(e)}
})
return [
{
data,
links: this.links,
categories: data.map(e => e.category).flat().map(name => ({name}))
}
]
}
},
data() {
return {
graph: null,
nodes: [],
links: [],
users: []
}
},
watch: {
graphData: {
deep: true, handler() {
this.refreshGraph()
}
}
},
methods: {
initGraph() {
let dom = document.querySelector("#RightGraph")
if (dom) {
this.graph = echarts.init(dom)
this.graph.setOption({
tooltip: {},
series: [
{
type: 'graph',
layout: 'none',
roam: true,
label: {
show: true,
position: 'right',
formatter: '{b}'
},
labelLayout: {
hideOverlap: true,
},
scaleLimit: {
min: 0.4,
max: 4
},
lineStyle: {
color: 'target',
curveness: 0.1
},
emphasis: {
focus: 'adjacency',
lineStyle: {
width: 5
}
}
}
]
})
this.graph.on('click', this.handleNodeClick)
}
},
refreshGraph() {
this.graph?.setOption({
series: this.graphData
})
},
getAppRoles(role) {
if (role) {
this.nodes.push({...role, category: '应用角色', value: "应用角色", symbolSize: 15})
} else this.instance.post(this.top.actions.list, null, {
params: {pageSize: 999}
}).then(res => {
if (res?.data) {
res.data.records.map(e => {
this.getUsers(e.users, e.id)
this.nodes.push({...e, category: '应用角色', value: "应用角色"})
})
}
})
},
getUsers(pending, source) {
pending?.map(e => {
if (!this.users.some(u => u.id == e.phone)) {
this.users.push({id: e.phone, name: e.name, symbolSize: 5, category: '用户', value: "用户"})
}
this.links.push({source, target: e.phone})
})
},
getPermissions({appId: id, id: roleId, name: category, dataIndex}) {
const addNodes = (list, source, category, pos) => {
list?.map(e => {
let node = {
...e,
symbolSize: 5,
category,
value: e.list?.length > 0 ? "应用" : "权限",
}
node = {...node, ...this.renderPosition(pos || node)}
this.nodes.splice(dataIndex, 0, node)
this.links.push({source, target: e.id})
addNodes(e.list, e.id, e.label, node)
})
}
id && this.instance.post(this.top.actions.detail, null, {
params: {id, roleId}
}).then(res => {
if (res?.data) {
addNodes(res.data.list, roleId, category)
}
})
},
handleNodeClick(v) {
let {data: role, dataIndex} = v
if (!this.nodes.some(e => e.category == role?.name)) {
role && this.getPermissions({...role, dataIndex})
}
},
renderPosition(node) {
node = JSON.parse(JSON.stringify(node))
let pos = {x: 0, y: 0}
if (node?.x) {
pos.x = Math.max(this.graph?.getWidth() / 3 * 2, node.x) + 100 + Math.random() * 50
pos.y = node.y + Math.random() * 100 - 50
} else if (node.value == '应用角色') {
pos.x = this.graph?.getWidth() / 3 - 200 + Math.random() * 200
pos.y = this.graph?.getHeight() / 2 - 100 + Math.random() * 200
} else if (node.value == '应用') {
pos.x = this.graph?.getWidth() / 3 * 2 - 100 + Math.random() * 100
pos.y = Math.random() * this.graph?.getHeight()
} else if (node.value == '用户') {
pos.x = Math.random() * 50
pos.y = Math.random() * this.graph?.getHeight()
} else {
pos.x = this.graph?.getWidth() - 100 + Math.random() * 100
pos.y = Math.random() * this.graph?.getHeight()
}
return pos
}
},
created() {
this.getAppRoles(this.app)
if (this.app?.id) {
this.getUsers(this.app.users, this.app.id)
this.getPermissions(this.app)
}
},
mounted() {
this.$nextTick(() => {
this.initGraph()
})
}
}
</script>
<style lang="scss" scoped>
.rightsGraph {
height: 100%;
::v-deep #RightGraph {
width: 100%;
height: 100%;
min-height: 500px;
}
}
</style>

View File

@@ -0,0 +1,211 @@
<template>
<section class="AppSystemAccount">
<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-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="160px">
<el-row type="flex" justify="center" align="middle" slot-scope="{row}">
<el-button type="text" @click="appAllot(row)">功能分配</el-button>
<el-button type="text" @click="handleDelete(row.id)">删除</el-button>
</el-row>
</el-table-column>
</ai-table>
</template>
</ai-list>
<!--添加账号功能分配-->
<ai-dialog :title="dialogTitle" :visible.sync="dialog" width="600px" @open="initDialogData"
@onConfirm="updateAccount" @closed="dialogForm={}">
<el-form ref="updateAccountForm" :model="dialogForm" :rules="rules" size="small"
label-width="120px">
<el-form-item required label="姓名" prop="name">
<el-input v-model.trim="dialogForm.name" placeholder="请输入..." clearable
:maxLength="15"/>
</el-form-item>
<el-form-item required label="手机号码" prop="phone">
<el-input v-model.trim="dialogForm.phone" placeholder="请输入..." clearable
:maxLength="11" :disabled="isEdit"/>
</el-form-item>
<el-form-item required label="角色" prop="roleId">
<el-select size="small" 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 label="行政地区" prop="areaId">
<ai-area-get v-model="dialogForm.areaId" :instance="instance" @select="handleAreaSelect"/>
</el-form-item>
</el-form>
</ai-dialog>
</section>
</template>
<script>
import {mapState} from "vuex";
export default {
name: "AppSystemAccount",
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: "姓名", slot: "name"},
{label: "联系方式", prop: "phone", align: 'center'},
{label: "角色", prop: "roleName", align: 'center'},
{label: "地区", prop: "areaName"},
{slot: "options"}
]
},
rules() {
return {
name: [{required: true, message: "请填写姓名"}],
// organizationId: [{required: true, message: "请选择党组织"}],
// unitId: [{required: true, message: "请选择单位"}],
// areaId: [{required: true, message: '请选择地区', trigger: 'change'}],
roleId: [{required: true, message: "请选择角色"}],
phone: [{required: true, message: "请输入手机号码"}]
}
},
disabledLevel() {
return this.user.info.areaList?.length || 0
}
},
data() {
return {
accountRoles: [],
page: {pageNum: 1, pageSize: 10, total: 0},
dialog: false,
dialogForm: {},
tableData: [],
search: {condition: ""},
ids: []
}
},
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
}
})
},
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(ids) {
this.$confirm("是否要删除该账号?").then(() => {
this.instance.post("/admin/user/del", null, {
params: {ids}
}).then(res => {
if (res?.code == 0) {
this.getTableData();
this.$message.success("删除成功!");
}
})
}).catch(() => 0)
},
handleAreaSelect(v) {
this.dialogForm.areaName = v?.[0]?.label
}
},
created() {
this.getTableData()
}
}
</script>
<style lang="scss" scoped>
.AppSystemAccount {
height: 100%;
::v-deep .avatar {
width: 40px;
height: 40px;
margin-right: 10px;
}
::v-deep .el-form {
.el-cascader, .el-select {
width: 100%;
}
}
}
</style>

View File

@@ -0,0 +1,193 @@
<template>
<section class="AppUserInfo">
<ai-detail>
<ai-title slot="title" title="个人中心" isShowBottomBorder/>
<template #content>
<ai-card title="个人资料">
<template #right>
<span style="color:#999" v-text="'(如需修改基本信息,请联系管理员)'"/>
</template>
<template #content>
<el-row type="flex" justify="space-between">
<ai-wrapper>
<ai-info-item label="姓名" :value="user.info.name"/>
<ai-info-item label="手机号码" :value="user.info.phone"/>
<ai-info-item label="角色" :value="user.info.roleName"/>
<ai-info-item label="部门" :value="user.info.departName"/>
<ai-info-item label="职位" :value="user.info.position"/>
</ai-wrapper>
<ai-avatar :value="user.info.avatar" :editable="false"/>
</el-row>
</template>
</ai-card>
<ai-card title="数据权限">
<template #right>
<span style="color:#999" v-text="'(如需修改基本信息,请联系管理员)'"/>
</template>
<template #content>
<ai-wrapper>
<ai-info-item label="所属地区" :value="user.info.areaList.join('')" isLine/>
<ai-info-item label="所属党组织" :value="user.info.organizationName" isLine/>
</ai-wrapper>
</template>
</ai-card>
<ai-card title="密码设置">
<template #right>
<el-button type="text" @click="submitForm">保存</el-button>
</template>
<template #content>
<el-form :model="form" ref="ruleForm" :rules="rules" label-width="100px" size="small">
<el-form-item label="绑定手机:" prop="phone">
<el-row type="flex" align="middle">
<span>{{ user.info.phone }}</span>
<el-button type="primary" style="margin-left: 8px" @click="getCode(user.info.phone,true)"
:disabled="codeBtn">获取验证码
<span v-if="num>0&&codeBtn" style="color:red;">({{ num }}s)</span>
</el-button>
</el-row>
</el-form-item>
<el-form-item label="验证码:" prop="code">
<el-input v-model.trim="form.code" clearable placeholder="请输入短信验证码"/>
<el-input style="position: fixed; bottom: -9999px"></el-input>
</el-form-item>
<el-form-item label="新密码:" prop="pass">
<el-input type="password" auto-complete="new-password" v-model.trim="form.pass" clearable
placeholder="8-16位需要包含字母和数字及特殊字符(~!@#$%^&*,.?_-)"
show-password/>
</el-form-item>
<el-form-item label="确认密码:" prop="checkPass">
<el-input type="password" auto-complete="new-password" placeholder="再次输入密码"
v-model.trim="form.checkPass" clearable
show-password/>
</el-form-item>
</el-form>
</template>
</ai-card>
</template>
</ai-detail>
</section>
</template>
<script>
import {mapMutations, mapState} from "vuex";
export default {
name: "AppUserInfo",
label: "个人中心",
props: {
instance: Function,
},
computed: {
...mapState(['user']),
rules() {
const validatePass = (rule, value, callback) => {
const reg = /^(?=.*\d)(?=.*[a-zA-Z])(?=.*[~!@#$%^&*,.?_-])[\da-zA-Z~!@#$%^&*,.?_-]{8,16}$/;
if (!reg.test(value)) {
callback(new Error('数字和字母及特殊字符(~!@#$%^&*,.?_-)组合,长度8到16位'));
} else {
if (this.form.checkPass !== '') {
this.$refs.ruleForm.validateField('checkPass');
}
callback();
}
}
return {
currentPass: [
{required: true, message: '请填写当前密码', trigger: 'blur'}
],
code: [
{required: true, message: '请填写验证码', trigger: 'blur'}
],
pass: [
{validator: validatePass, trigger: 'blur', required: true}
],
checkPass: [
{
validator: (r, v, cb) => v ? v != this.form.pass ? cb('两次输入密码不一致') : cb() : cb('请再次输入密码'),
trigger: 'blur',
required: true
}
],
}
}
},
data() {
return {
form: {},
timer: null,
codeBtn: false,
num: 60,
}
},
methods: {
...mapMutations(['SignOut']),
getCode(phone, flag) {
const TEL_REGEXP = /^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\d{8}$/;
if (TEL_REGEXP.test(phone)) {
this.instance.post(`/admin/user/checkPhone`, null, {
params: {phone, flag}
}).then(res => {
if (res.code == 0) {
this.$message.success("请查看手机短信!");
this.timer = setInterval(() => {
if (this.num > 0) {
this.codeBtn = true;
this.num--;
} else if (this.num == 0) {
this.codeBtn = false;
this.num = 60;
clearInterval(this.timer);
}
}, 1000)
} else {
this.$message.error("验证码发送失败!");
}
})
} else {
this.$message.error("手机号格式错误!");
}
},
submitForm() {
this.$refs.ruleForm.validate(v => {
if (v) {
let {pass: newPwd, code} = this.form
this.instance.post(`/admin/user/update-pwd`, null, {
params: {
phone: this.user.info.phone,
newPwd, code
}
}).then(res => {
if (res?.code == 0) {
this.$confirm("村微提醒您,更换密码成功!", {
showCancelButton: false
}).then(() => this.SignOut()).catch(() => 0)
}
})
}
})
}
}
}
</script>
<style lang="scss" scoped>
.AppUserInfo {
height: 100%;
::v-deep .ai-list__content--wrapper {
flex-direction: column;
}
::v-deep .el-input__inner {
-webkit-text-security: disc !important;
}
}
</style>

View File

@@ -0,0 +1,248 @@
<template>
<section class="AiAddressBookMenu">
<div class="tabsPane">
<h2 v-for="tab in tabs" :key="tab.name" :class="{tabActive:current==tab.name}"
@click="handleTabClick(tab)">{{ tab.label }}</h2>
</div>
<div class="contentPane">
<el-input :placeholder="`请输入${currentTab.label}名称`"
size="small" v-model="search" suffix-icon="iconfont iconSearch"
@change="handleSearchChange"/>
<div v-if="isTagType" class="addressBook-left__tags">
<div @click="selected=item" v-for="(item, index) in tags" :key="index"
class="addressBook-left__tags--item"
:class="{'addressBook-left__tags--item-active':selected.id == item.id}">
<span>{{ item.tagname }}</span>
</div>
</div>
<div class="AiAddressBookMenu-wrapper" v-else>
<div class="AiAddressBookMenu-tree">
<el-tree
ref="tree"
node-key="id"
highlight-current
:filter-node-method="handleTreeFilter"
:props="defaultProps" :data="list"
:default-expanded-keys="treeRoot"
@current-change="v=>selected=v">
<div class="tree-container" slot-scope="{ data }">
<span>{{ data.name }}</span>
</div>
</el-tree>
</div>
</div>
</div>
</section>
</template>
<script>
/**
* 通讯录选择器
*/
export default {
name: "AiAddressBookMenu",
props: {
instance: Function,
},
computed: {
tabs() {
return [
{label: "组织架构", name: 0},
{label: "标签", name: 1}
]
},
currentTab() {
return this.tabs.find(e => e.name == this.current) || {}
},
isTagType() {
return this.current == 1
},
defaultProps() {
return {
children: 'children',
label: 'name'
}
},
tags() {
return this.list?.filter(e => !this.search || e.tagname?.indexOf(this.search) > -1)
},
treeRoot() {
let root = this.list?.[0]
return root ? [root?.id] : []
}
},
data() {
return {
current: 0,
search: "",
list: [],
origin: [],
selected: {}
}
},
watch: {
selected(v) {
v && this.$emit('select', {...v, type: this.current})
}
},
methods: {
handleTabClick(tab) {
this.current = tab.name
this.isTagType ? this.getTags() : this.getUnits()
this.$emit('tabClick')
},
handleTreeFilter(v, data) {
return data?.name?.indexOf(v) > -1
},
handleSearchChange(v) {
if (this.isTagType) {
} else {
this.$refs.tree?.filter(v)
}
},
handleTagClick(tag) {
this.$emit('tag', tag)
this.selected = tag
},
getUnits() {
this.instance.post(`/app/wxcp/wxdepartment/listAll`).then(res => {
if (res?.data) {
this.list = res.data?.filter(e => !e.parentid)
this.list.map(p => this.addChild(p, res.data, {parent: 'parentid'}))
this.$nextTick(() => {
this.$refs.tree.setCurrentKey(res.data[0].id)
this.$emit('select', res.data[0])
})
}
})
},
getTags() {
this.instance.post(`/app/wxcp/wxtag/listAll`).then(res => {
if (res?.data) {
this.origin = JSON.parse(JSON.stringify(res.data))
this.list = res?.data
}
})
}
},
created() {
this.getUnits()
}
}
</script>
<style lang="scss" scoped>
.AiAddressBookMenu {
width: 100%;
height: 100%;
background: #FAFAFB;
.tabsPane {
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;
&.tabActive {
color: #2266FF;
border-bottom: 2px solid #2266FF;
}
}
}
.AiAddressBookMenu-wrapper {
height: calc(100% - 32px);
.AiAddressBookMenu-tree {
width: 100%;
height: 100%;
overflow: auto;
}
}
.contentPane {
height: calc(100% - 56px);
margin: 8px;
overflow: auto;
.addressBook-left__tags--item {
cursor: pointer;
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;
}
}
span {
color: #222;
font-size: 14px;
}
::v-deep .el-tree {
width: 100%;
margin-top: 4px;
background: transparent;
width: fit-content;
min-width: 100%;
.el-tree-node__content {
display: inline-flex;
min-width: 100%;
height: 32px;
&:hover {
background: #E8EFFF;
color: #222222;
border-radius: 2px;
}
}
.is-current > .el-tree-node__content {
background: #2266FF;
&:hover {
background: #2266FF;
color: #fff;
}
span {
color: #fff;
font-weight: bold;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,35 @@
<template>
<section class="AiDrag">
<vue-draggable-resizable v-bind="$attrs">
<slot/>
</vue-draggable-resizable>
</section>
</template>
<script>
import 'vue-draggable-resizable/dist/VueDraggableResizable.css'
import VueDraggableResizable from 'vue-draggable-resizable'
export default {
name: "AiDrag",
components: {VueDraggableResizable},
props: {
type: {default: "show"} //show:只拖拽
}
}
</script>
<style lang="scss" scoped>
.AiDrag {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
pointer-events: none;
::v-deep.vdr {
pointer-events: auto;
}
}
</style>

View File

@@ -0,0 +1,33 @@
<template>
<section class="AiEditBtn">
<el-button v-if="!edit" type="text" @click="handleOper('edit')">编辑</el-button>
<template v-else>
<el-button type="text" @click="handleOper('submit')">保存</el-button>
<el-button type="text" @click="handleOper('cancel')">取消</el-button>
</template>
</section>
</template>
<script>
export default {
name: "AiEditBtn",
data() {
return {
edit: false
}
},
methods: {
handleOper(event) {
if (event != "submit") {
this.edit = !this.edit
this.$emit(event)
} else this.$emit(event, () => this.edit = !this.edit)
}
}
}
</script>
<style lang="scss" scoped>
.AiEditBtn {
}
</style>

45
core/index.js Normal file
View File

@@ -0,0 +1,45 @@
/**
* 系统业务模块
* @param Vue 外部接入Vue
* @param params showList:打印加载的应用;apps:加载的应用文件名数组
*/
const install = function (Vue, params) {
if (install.installed) return Promise.resolve()
else {
// 遍历工作控件内的应用
let apps = []
let contexts = require.context('.', true, /\.(\/.+)\/App[^\/]+\.vue$/)
if (contexts) {
contexts.keys().map(e => {
if (contexts(e).default) {
if (params?.apps) {
if (params?.apps.includes(contexts(e).default.name)) {
apps.push(contexts(e).default)
Vue.component(contexts(e).default.name, contexts(e).default)
}
} else {
apps.push(contexts(e).default)
Vue.component(contexts(e).default.name, contexts(e).default)
}
}
})
// apps.map(e=>{
// console.log(e.name,e.label)
// })
!!params?.showList && console.log(apps.map(e => e.name))
}
return Promise.resolve(apps)
}
}
// 判断是否是直接引入文件
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
export default {
// 导出的对象必须具有 install才能被 Vue.use() 方法安装
install
}

12
core/package.json Normal file
View File

@@ -0,0 +1,12 @@
{
"name": "dvcp-core",
"description": "系统业务模块",
"version": "1.0.13",
"main": "dist/dvcp-core.common.js",
"files": [
"dist"
],
"publishConfig": {
"registry": "http://cli.sinoecare.net"
}
}

122
examples/App.vue Normal file
View File

@@ -0,0 +1,122 @@
<template>
<div id="app">
<header-nav v-if="showTools" title="web端产品库">
<template #right>
<div @click="showTools=false">隐藏工具栏</div>
<div @click="handleLogin">点此登录</div>
</template>
</header-nav>
<el-row class="fill mar-t48" type="flex">
<slider-nav v-if="showTools"/>
<main-content class="fill"/>
</el-row>
<div v-if="dialog" class="sign-box">
<ai-sign style="margin: auto" :instance="$request" :action="{login}"
visible @login="getToken" :showScanLogin="false"/>
</div>
<el-button type="info" v-if="!showTools" class="fixedBtn" @click="showTools=true">显示工具栏</el-button>
</div>
</template>
<script>
import SliderNav from "./components/sliderNav";
import MainContent from "./components/mainContent";
import HeaderNav from "./components/headerNav";
import {mapActions, mapMutations, mapState} from "vuex";
export default {
name: 'app',
components: {HeaderNav, MainContent, SliderNav},
computed: {
...mapState(['user']),
login() {
let url = '/auth/oauth/token';
/project\/sass/g.test(location.pathname) && (url += "?corpId=ww596787bb70f08288")
return url
},
},
data() {
return {
dialog: false,
showTools: true,
}
},
methods: {
...mapMutations(['setToken', 'setFinanceUser']),
...mapActions(['getUserInfo']),
getToken(params) {
if (params.access_token) {
this.setToken([params.token_type, params.access_token].join(' '))
this.dialog = false
this.$message.success("登录成功,正在刷新页面...")
location.reload()
} else this.$message.error(params.msg || "登录失败!")
},
handleLogin() {
this.$request.delete("/auth/token/logout").finally(() => {
this.dialog = true
})
},
},
created() {
wx = jWeixin
if (this.user.token) this.getUserInfo().then(() => {
if (/^\/project\/xiushan/.test(location.pathname)) {
this.setFinanceUser()
}
})
}
}
</script>
<style lang="scss">
html, body {
width: 100%;
height: 100%;
margin: 0;
}
.mar-t48 {
margin-top: 48px;
}
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
overflow: hidden;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
.fixedBtn {
position: fixed;
top: 0;
right: 60px;
opacity: 0;
&:hover {
opacity: 1;
}
}
li {
list-style-type: none;
}
.sign-box {
z-index: 99;
margin: -10px;
display: flex;
position: fixed;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.2);
}
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
examples/assets/file.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,273 @@
<template>
<div class="headerNav navBg">
<div style="position: relative">
<ai-icon type="logo" :icon="'iconcunwei'"/>
<ai-icon type="logo" :icon="'iconcunwei'" class="textShadow"/>
</div>
<span class="headerTitle">{{ title }}<div class="textShadow" v-html="title"/></span>
<el-row type="flex" align="middle" class="toolbar">
<slot v-if="$slots.right" name="right"/>
</el-row>
<el-dropdown @visible-change="v=>isClick=v" @command="doMenu" class="rightDropdown">
<el-row type="flex" align="middle">
<el-avatar :src="user.info.avatar">
{{ defaultAvatar }}
</el-avatar>
<span>{{ [user.info.name, user.info.roleName].join(" - ") }}</span>
<i :class="dropdownIcon"/>
</el-row>
<el-dropdown-menu>
<el-dropdown-item command="user">用户中心</el-dropdown-item>
<el-dropdown-item command="signOut">退出</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</template>
<script>
import {mapState} from "vuex";
export default {
name: 'headerNav',
props: {
title: {default: ""}
},
data() {
return {
isClick: false,
drawer: false,//抽屉
count: 0,
filesList: [],
fileName: '',
badgeNum: 0,
dvOptions: []
}
},
computed: {
...mapState(['user']),
dropdownIcon() {
return this.isClick ? 'el-icon-caret-top' : 'el-icon-caret-bottom'
},
defaultAvatar() {
return this.user.info.name?.slice(-2) || "无名"
}
},
methods: {
// 获取最新的安卓、ios下载二维码
doMenu(comm) {
switch (comm) {
case 'signOut':
//登出
this.$confirm("是否要登出?", {type: "warning"}).then(() => {
this.$store.commit("SignOut")
}).catch(() => {
})
break;
case 'user':
this.$router.push({name: "个人中心"})
break;
}
},
}
}
</script>
<style lang="scss" scoped>
.headerNav {
display: flex;
align-items: center;
width: 100%;
background-repeat: no-repeat;
background-size: 100% 48px;
position: fixed;
z-index: 99;
height: 48px;
padding-left: 24px;
box-sizing: border-box;
top: 0;
color: white;
font-size: 14px;
.AiIcon {
font-size: 38px;
width: auto;
height: auto;
background: linear-gradient(180deg, #FFFFFF 0%, #CCDBF6 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
&:hover {
color: white;
}
}
.headerTitle {
flex: 1;
min-width: 0;
font-size: 24px;
color: #FFF;
line-height: 28px;
background: linear-gradient(180deg, #FFFFFF 0%, #CCDBF6 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
font-weight: bold;
margin-left: 8px;
position: relative;
}
.textShadow {
position: absolute;
top: 0;
text-shadow: 0 2px 0 #384DC3;
color: transparent;
z-index: -1;
}
::v-deep.toolbar {
gap: 12px;
margin-right: 32px;
& > div {
padding: 0 12px;
&:hover {
cursor: pointer;
color: rgba(#fff, .8);
}
}
}
.el-dropdown {
height: 48px;
line-height: 48px;
color: #fff;
padding: 0 12px;
&:hover {
background-color: rgba(46, 51, 68, .15);
color: white;
}
}
.el-image {
margin: 12px 0 12px 16px;
}
.rightDropdown {
font-size: 12px;
padding: 0 16px;
height: 48px;
background: rgba(#fff, .1);
.el-row {
gap: 4px;
}
}
}
::v-deep .downLoad_main {
width: 100%;
height: 100%;
padding: 16px;
box-sizing: border-box;
.search_top {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 8px;
}
.infinite-list {
width: 100%;
height: 100%;
.infinite-list-item {
width: 100%;
padding: 8px;
box-sizing: border-box;
background: rgba(255, 255, 255, 1);
border-radius: 4px;
border: 1px solid rgba(208, 212, 220, 1);
margin-bottom: 8px;
display: flex;
justify-content: space-between;
.left {
display: flex;
justify-content: center;
align-items: center;
width: 30px;
.svg {
width: 24px;
height: 24px;
vertical-align: middle;
}
}
.middle {
flex: 1;
.fileName {
color: #333333;
font-size: 14px;
}
p:nth-child(2) {
color: #999999;
font-size: 12px;
span {
padding: 0 4px;
}
span:nth-child(2) {
border-right: solid 1px #999999;
}
span:nth-child(3) {
border-right: solid 1px #999999;
}
}
}
.right {
display: flex;
justify-content: center;
align-items: center;
font-size: 12px;
width: 90px;
text-align: center;
span {
color: #999999;
}
i {
display: block;
width: 50px;
color: #5088FF;
font-size: 12px;
cursor: pointer;
}
}
}
}
::-webkit-scrollbar {
width: 4px;
background-color: #eee;
}
::-webkit-scrollbar-thumb {
background-color: #8888;
}
}
</style>

View File

@@ -0,0 +1,163 @@
<template>
<section class="mainContent">
<el-tabs class="layout" type="card" :value="currentTab" @tab-click="handleTabClick"
@tab-remove="handleTabRemove">
<el-tab-pane label="默认页" class="layoutItem">
<ai-empty>欢迎使用村微产品库</ai-empty>
</el-tab-pane>
<el-tab-pane v-for="op in tabs" :key="op.name" :closable="op.name!='工作台'" :name="op.name" :label="op.label" lazy>
<router-view v-if="currentTab==op.name"/>
</el-tab-pane>
</el-tabs>
</section>
</template>
<script>
import {mapState} from "vuex";
export default {
name: "mainContent",
computed: {
...mapState(['apps']),
currentTab() {
let {name, query, hash} = this.$route
return [name?.replace(query?.id, ''), query?.id, hash].join("") || "0"
}
},
data() {
return {
tabs: []
}
},
watch: {
$route: {
immediate: true,
handler() {
this.getTabs("route")
}
},
},
methods: {
handleTabClick({name}) {
let {name: route, query, hash} = this.tabs.find(e => e.name == name),
exps = []
query.id && exps.push(query.id)
hash && exps.push(hash)
let reg = new RegExp(`(${exps.join("|")})`, 'g')
this.$router.push({name: route.replace(reg, ''), query, hash})
},
handleTabRemove(id = this.currentTab) {
let tabs = JSON.parse(JSON.stringify(this.tabs)),
index = tabs?.findIndex(e => id == e.name)
if (id == this.currentTab) {
let next = tabs?.[index + 1] || tabs?.[index - 1]
next ? this.handleTabClick(next) : this.$router.push({path: '/'})
}
this.tabs.splice(index, 1)
},
getTabs(from) {
let {name, query, hash} = this.$route
console.log(`getTabs>>>>>>>>>%s>>>>>>>%s`, from, name)
let tab = this.tabs.find(e => e.name == this.currentTab),
tabName = [name, query?.id, hash].join("")
if (tab) {
} else if (!name) {
} else if (tabName) {
let menu = this.apps.find(e => e.name == name)
this.tabs.push({name: tabName, query, hash, label: menu?.label})
}
},
},
created() {
this.getTabs("created")
}
}
</script>
<style lang="scss" scoped>
.mainContent {
height: 100%;
width: 100%;
::v-deep.layout {
height: 100%;
background: #F5F6F9;
display: flex;
flex-direction: column;
& > .el-tabs__header {
margin-bottom: 0;
background: linear-gradient(180deg, #FCFCFC 0%, #E0E2E4 100%);
height: 40px;
display: flex;
align-items: flex-end;
border: none;
.el-tabs__nav {
border: none;
}
.el-tabs__item {
padding: 0 8px 0 12px;
text-align: left;
min-width: 130px;
height: 36px;
line-height: 36px;
border: none;
color: #555;
font-size: 12px;
& + .el-tabs__item {
margin-left: 2px;
}
.el-icon-close {
float: right;
width: auto;
height: 100%;
line-height: 36px;
background: transparent;
font-size: 16px;
color: #89b;
&:hover {
color: #000;
}
}
&.is-active {
border: 1px solid #D8DCE3;
border-bottom: none;
border-radius: 4px 4px 0 0;
background: #F5F6F9;
color: #222;
&:after {
display: none;
}
}
&:after {
position: absolute;
right: 0;
content: " ";
width: 1px;
background: #D8DCE3;
height: 24px;
top: 50%;
transform: translateY(-50%);
}
}
}
.el-tabs__content {
flex: 1;
min-height: 0;
.el-tab-pane {
height: 100%;
}
}
}
}
</style>

View File

@@ -0,0 +1,262 @@
<template>
<section class="sliderNav">
<el-input class="searchApp" size="small" v-model="searchApp" placeholder="搜索应用" clearable
prefix-icon="iconfont iconSearch" @change="recordSearch"/>
<el-scrollbar class="ai-menu">
<div v-for="(item,i) in navs" :key="i">
<div class="rootMenu" :class="{isActive:menuPath.includes(item.name)}"
@click.stop="openKidMenu(item)">
<i class="prep-icon" :class="item.style||'iconfont iconloudongmoxing'"/>
<span class="menuName fill" v-text="item.label"/>
<el-badge type="warning" :hidden="!item.project" :value="item.project"/>
<i v-if="item.children" class="iconfont" :class="arrowIcon(item.showChildren)"/>
</div>
<div class="kidMenu" v-if="item.showChildren" @click.stop>
<div class="kidPane">
<div class="submenu wrap" flex v-for="menu in item.children" :key="menu.name">
<b v-text="menu.label" :class="{menuBtn:menu.type==1,current:menuPath.includes(menu.name)}"
@click="handleSelect(menu)"/>
<div class="menuBtn" v-for="kid in menu.children" :key="kid.name" v-text="kid.label"
@click="handleSelect(kid)"
:class="{current:menuPath.includes(kid.name)}"/>
</div>
</div>
</div>
</div>
<div class="divider"/>
</el-scrollbar>
</section>
</template>
<script>
import {mapState} from "vuex";
export default {
name: "sliderNav",
data() {
return {
searchApp: "",
}
},
computed: {
...mapState(['user', 'apps']),
navs() {
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 => {
if (/\/project\//.test(e.path)) {
e.project = e.path.replace(/.*project\/([^\/]+)\/.+/, '$1')
} else if (/\/core\//.test(e.path)) {
e.project = "core"
}
return e
})
},
isConsoleRoute() {
return this.$route.name == "工作台"
},
menuPath() {
let paths = [], current = this.apps?.find(e => e.name == this.$route.name)
const findParent = name => {
let menu = this.apps?.find(e => e.name == name)
if (menu) {
paths.push(menu.name)
if (!!menu.parentId) findParent(menu.parentId)
}
}
if (current) {
findParent(current.name)
}
return paths
}
},
methods: {
openKidMenu(parent) {
if (parent.children) {
parent.showChildren = !parent.showChildren
} else {
this.handleSelect(parent)
}
},
handleSelect(item) {
if (!item.path) return
if (item.name == this.$route.name) {
//避免同一路由跳转的BUG vue-router官方BUG
} else {
let {name, path} = item
if (/\?app=/.test(path)) {
this.goto({name, query: {app: path.replace(/.+\?app=/, '')}})
} else if (/\?moduleId=/.test(path)) {
this.goto({name, query: {moduleId: path.replace(/.+\?moduleId=/, '')}})
} else {
this.goto({name})
}
}
},
goto(item) {
this.$router.push(item)
},
subMenuIcon(flag) {
return flag ? 'iconfont iconArrow_Down' : "iconfont iconArrow_Right"
},
arrowIcon(v) {
return v ? "iconArrow_Down" : "iconArrow_Right"
},
recordSearch() {
localStorage.setItem("searchApp", this.searchApp)
},
},
created() {
this.searchApp = localStorage.getItem("searchApp") || ""
}
}
</script>
<style lang="scss" scoped>
.sliderNav {
min-width: 200px;
height: 100%;
transition: width .1s;
display: flex;
justify-content: space-between;
flex-direction: column;
border-right: 1px solid #e5e5e5;
flex-shrink: 0;
box-sizing: border-box;
background: #EFF1F4;
color: #222;
position: relative;
.kidMenu {
padding: 0 16px;
background: #EFF1F4;
.rootName {
font-size: 20px;
color: #333;
cursor: default;
}
.kidPane {
font-size: 13px;
.submenu {
margin-top: 8px;
width: 100%;
color: #aaa;
& > b {
width: 100%;
line-height: 28px;
}
& > * {
cursor: default;
}
}
.menuBtn {
display: block;
width: 50%;
cursor: pointer;
line-height: 32px;
color: #333;
flex-shrink: 0;
&:hover {
color: #26f;
}
&.current {
color: #26f;
}
}
}
}
.rootMenu {
padding: 0 16px;
display: flex;
align-items: center;
height: 44px;
cursor: pointer;
box-shadow: 0px -1px 0px 0px #D8DCE3 inset, 0px 1px 0px 0px #FFF inset, -1px 0px 0px 0px #E5E5E5 inset;
gap: 8px;
font-size: 13px;
.iconfont {
color: #89B;
font-size: 20px;
}
&.isActive {
color: #26f;
.iconfont {
color: #26f !important;
}
}
&:hover {
color: #26f;
}
}
::v-deep .ai-menu {
padding-left: 0;
flex: 1;
min-height: 0;
.el-scrollbar__wrap {
overflow-x: auto;
}
&::-webkit-scrollbar {
display: none;
}
}
::v-deep .searchApp {
display: flex;
align-items: center;
height: 44px;
padding: 0 16px;
box-shadow: 0px -1px 0px 0px #E5E5E5 inset;
.el-input__inner {
border: none;
background: inherit;
padding: 0 28px;
}
.el-input__prefix {
left: 16px;
.iconSearch {
font-size: 20px;
width: fit-content;
color: #89B;
line-height: 44px;
}
}
}
.divider {
color: #aaa;
border-top: 1px solid #ddd;
position: relative;
font-size: 12px;
margin: 16px 16px 32px;
&:before {
content: "到达底部";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 0 16px;
background: #EFF1F4;
white-space: nowrap;
}
}
}
</style>

34
examples/main.js Normal file
View File

@@ -0,0 +1,34 @@
import Vue from 'vue';
import App from './App.vue';
import ui from 'element-ui';
import router from './router/router';
import axios from './router/axios';
import utils from './utils';
import vcUI from 'dvcp-ui';
import 'dvcp-ui/lib/styles/common.scss';
import 'dvcp-ui/lib/dvcp-ui.css';
import store from './store';
import dataV from '@jiaminghi/data-view';
import dvui from '../project/dvui/entries'
Vue.use(ui);
Vue.use(vcUI);
Vue.use(dvui)
//富文本编辑器配置
Vue.config.productionTip = false;
Object.keys(utils).map((e) => (Vue.prototype[e] = utils[e]));
Vue.prototype.$request = axios
const app = new Vue({
router,
store,
render: h => h(App)
});
let theme = null
store.dispatch('getSystem').then(({colorScheme}) => {
theme = JSON.parse(colorScheme || null)
Vue.prototype.$theme = theme?.web || "blue"
return import(`dvcp-ui/lib/styles/theme.${theme?.web}.scss`).catch(() => 0)
}).finally(() => {
!theme ? app.$mount('#app') : import(`dvcp-ui/lib/styles/common.scss`).finally(() => app.$mount('#app'))
})

View File

@@ -0,0 +1,49 @@
import store from "../store";
import appEntry from "../views/appEntry";
import {waiting} from "../utils";
import router from "./router";
import axios from "./axios";
export default {
routes: [],
init() {
//约束正则式
store.commit("cleanApps")
this.routes = []
// 自动化本工程应用
return this.loadApps()
},
loadApps() {
//新App的自动化格式
let apps = require.context('../../packages/', true, /\.(\/.+)\/App[A-Z][^\/]+\.vue$/, 'lazy'),
projects = require.context('../../project/', true, /\.(\/.+)\/App[A-Z][^\/]+\.vue$/, 'lazy')
const promise = (mods, base) => Promise.all(mods.keys().map(path => mods(path).then(file => {
if (file.default) {
let {name, label} = file.default,
addApp = {
name: path.replace(/\.\/?(vue)?/g, '')?.split("/").join("_"), label: label || name,
path: `/${base}${path.replace(/\.(\/.+\/App.+)\.vue$/, '$1')}`,
component: appEntry,
module: file.default
}
waiting.setContent(`加载${name}...`)
router.addRoute(addApp)
//命名规范入口文件必须以App开头
return store.commit("addApp", addApp)
} else return 0
})))
waiting.init({innerHTML: '应用加载中..'})
Promise.all([
promise(apps, "packages"),
promise(projects, "project")
]).then(() => {
axios.post("/node/wechatapps/addOrUpdate", {
type: "web",
list: this.routes().map(({path: libPath, label, module: {name}, name: id}) => ({
id, type: 'web', libPath, label, name
}))
}, {baseURL: "/ns"}).catch(() => 0)
waiting.close()
})
}
}

28
examples/router/axios.js Normal file
View File

@@ -0,0 +1,28 @@
import instance from 'dvcp-ui/lib/js/request'
import {Message} from 'element-ui'
let baseURLs = {
production: "/",
development: '/lan'
}
instance.defaults.baseURL = baseURLs[process.env.NODE_ENV]
instance.interceptors.request.use(config => {
if (config.url.startsWith("/node")) {
config.baseURL = "/ns"
} else if (/\/project\/beta/.test(location.pathname)) {
config.baseURL = "/wg"
} else if (/\/project\/sass/.test(location.pathname)) {
config.baseURL = "/saas"
} 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", "/omsapi"].includes(config.baseURL)) {
config.url = config.url.replace(/(app|auth|admin)\//, "")
}
return config
}, error => Message.error(error))
export default instance

18
examples/router/router.js Normal file
View File

@@ -0,0 +1,18 @@
import VueRouter from 'vue-router'
import autoRoutes from './autoRoutes'
import Vue from "vue";
autoRoutes.init()
Vue.use(VueRouter)
export default new VueRouter({
mode: 'history',
hashbang: false,
routes: [{path: "/", redirect: "/v", name: "产品库", component: import('../App')}],
scrollBehavior(to) {
if (to.hash) {
return {
selector: to.hash
}
}
}
})

28
examples/store/index.js Normal file
View File

@@ -0,0 +1,28 @@
import Vue from 'vue'
import Vuex from 'vuex'
import preState from 'vuex-persistedstate'
import * as modules from "dvcp-ui/lib/js/modules"
import axios from "../router/axios";
Vue.use(Vuex)
export default new Vuex.Store({
state: {
apps: []
},
mutations: {
addApp(state, app) {
state.apps.push(app)
},
cleanApps(state) {
state.apps = []
},
setFinanceUser(state) {
axios.post("appfinancialorganizationuser/checkUser").then(res => {
state.user.financeUser = res.data
}).catch(() => 0)
}
},
modules,
plugins: [preState()]
})

101
examples/utils/index.js Normal file
View File

@@ -0,0 +1,101 @@
import {MessageBox} from 'element-ui'
import store from '../store'
import tools from 'dvcp-ui/lib/js/utils'
const addChildParty = (parent, pending) => {
let doBeforeCount = pending.length
parent["children"] = parent["children"] || []
pending.map((e, index, arr) => {
if (e.partyOrgParentId == parent.partyOrgId) {
parent.children.push(e)
arr.splice(index, 1)
addChildParty(parent, arr)
}
})
if (parent.children.length == 0) {
delete parent.children
}
if (pending.length > 0 && doBeforeCount > pending.length) {
parent.children.map(c => addChildParty(c, pending))
}
}
/**
* 封装提示框
*/
const $confirm = (content, options) => {
return MessageBox.confirm(content, {
type: "warning",
confirmButtonText: "确认",
center: true,
title: "提示",
dangerouslyUseHTMLString: true,
...options
})
}
/**
* 封装权限判断方法
*/
const $permissions = flag => {
const buttons = store.state.user.info.buttons
if (buttons) return buttons.some(b => b.id == flag || b.permission == flag)
else return false
}
const $decimalCalc = (...arr) => {
//确认提升精度
let decimalLengthes = arr.map(e => {
let index = ("" + e).indexOf(".")
return ("" + e).length - index
})
let maxDecimal = Math.max(...decimalLengthes), precision = Math.pow(10, maxDecimal)
//计算
let intArr = arr.map(e => (Number(e) || 0) * precision)
//返回计算值
return intArr.reduce((t, a) => t + a) / precision
}
export const waiting = {
init(ops, count) {
if (document.body) {
let div = document.createElement('div')
div.id = "ai-waiting"
div.className = "el-loading-mask is-fullscreen"
div.style.zIndex = '202204271710'
div.style.textAlign = 'center'
div.style.lineHeight = '100vh'
div.style.color = '#26f'
div.style.fontSize = '20px'
div.style.background = 'rgba(255,255,255,.8)'
div.style.backdropFilter = 'blur(6px)'
document.body.appendChild(div)
} else if (count < 10) {
setTimeout(() => this.init(ops, ++count), 500)
}
},
getDom() {
return document.querySelector('#ai-waiting')
},
setContent(html) {
let div = this.getDom()
div.innerHTML = html
},
close() {
let div = this.getDom()
div.parentElement.removeChild(div)
}
}
export default {
...tools,
addChildParty,
$confirm,
$permissions,
$decimalCalc,
$waiting: waiting
}

View File

@@ -0,0 +1,37 @@
<template>
<section class="appEntry">
<component v-if="app" :is="app" :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() {
let app = this.apps.find(e => e.name == this.$route.name)
return app ? app.module : ""
}
}
}
</script>
<style lang="scss" scoped>
.appEntry {
width: 100%;
flex: 1;
min-width: 0;
min-height: 0;
height: 100%;
& > * {
height: 100%;
}
}
</style>

13
examples/views/index.vue Normal file
View File

@@ -0,0 +1,13 @@
<template>
<router-view />
</template>
<script>
export default {
name: "index"
}
</script>
<style scoped>
</style>

15
index.html Normal file
View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>村务云应用库-展示页面</title>
<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js" referrerpolicy="origin"></script>
<script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js" referrerpolicy="origin"></script>
</head>
<body>
<div id="app"></div>
<script type="module" src="/examples/main.js"></script>
</body>
</html>

36
package.json Normal file
View File

@@ -0,0 +1,36 @@
{
"name": "dvcp-vite-webapps",
"private": false,
"version": "0.0.0",
"main": "lib/dvcp-vite-webapps.umd.js",
"scripts": {
"dev": "vite",
"preview": "vite preview",
"lib": "vite build --outDir lib --emptyOutDir&&npm unpublish --force&&npm publish",
"lib:core": "vue-cli-service build --target lib --dest core/dist core/index.js --name vc-app-core&&npm unpublish --force&&npm publish",
"lib:project": "node project/build.js",
"lib:all": "node project/allProject.js&&npm unpublish --workspaces --force&&npm publish --workspaces",
"ui": "npm i dvcp-ui@latest"
},
"workspaces": [
"project/*"
],
"devDependencies": {
"v-viewer": "^1.6.4",
"vite": "^2.9.5",
"vite-plugin-vue2": "^2.0.0",
"vue": "^2.6.14",
"vue-router": "^3.3.4",
"vue-template-compiler": "^2.6.14",
"vuex-persistedstate": "^3.2.1"
},
"dependencies": {
"dvcp-dv-ui": "^2.0.1",
"dvcp-ui": "^1.42.2",
"element-ui": "^2.15.8",
"mp4box": "^0.4.1",
"print-js": "^1.0.63",
"sass": "^1.51.0",
"vue-draggable-resizable": "^2.3.0"
}
}

View File

@@ -0,0 +1,58 @@
<template>
<section class="preview">
<ai-dv-wrapper :views="[{label: '返回'}]" :theme="config.theme" @change="$router.back()" v-if="screenId" :title="info.name">
<ai-dv-background
:theme="config.theme"
v-if="config.length || config.theme === '1'"
:src="config.theme === '1' ? 'https://cdn.cunwuyun.cn/dvcp/dv/img/dj-bg.png' : config.backgroundImage[0].url">
</ai-dv-background>
<app-gigscreen-viewer :urlPrefix="urlPrefix" :instance="instance" :dict="dict" :id="screenId"/>
</ai-dv-wrapper>
</section>
</template>
<script>
import AppGigscreenViewer from "../../viewer/AppGigscreenViewer";
export default {
name: "preview",
components: {AppGigscreenViewer},
props: {
instance: Function,
dict: Object,
permissions: Function,
urlPrefix: {
type: String,
default: '/app'
}
},
computed: {
screenId: v => v.$route.query.id
},
data() {
return {
info: {},
config: {}
}
},
methods: {
getDvData() {
let {id} = this.$route.query
this.instance.post(`${this.urlPrefix}/appdiylargescreen/queryLargeScreenDetailById?id=${id}`).then(res => {
if (res?.data) {
this.info = res.data
this.config = JSON.parse(res.data.config).dashboard
}
})
}
},
created() {
this.getDvData()
}
}
</script>
<style lang="scss" scoped>
.preview {
}
</style>

View File

@@ -0,0 +1,66 @@
<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: 'AppConvenienceAddressBook',
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>

View File

@@ -0,0 +1,132 @@
<template>
<ai-detail>
<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 ref="CBookForm" class="ai-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 style="width: 100%" label="名称" prop="name" :rules="[{ required: true, message: '请输入名称', trigger: 'blur' }]">
<el-input size="small" placeholder="请输入名称" show-word-limit v-model="form.name" :maxlength="30"></el-input>
</el-form-item>
<el-form-item style="width: 100%" label="类型" prop="type" :rules="[{ required: true, message: '请输入类型', trigger: 'change' }]">
<el-input size="small" placeholder="请输入类型" v-model="form.type"></el-input>
</el-form-item>
<el-form-item style="width: 100%" label="电话" prop="phone" :rules="[{required: true, validator: regPhone, trigger: 'blur' }]">
<el-input size="small" placeholder="请输入电话" show-word-limit maxlength="11" v-model="form.phone"></el-input>
</el-form-item>
<el-form-item style="width: 100%;" label="是否公开" prop="isPublic" :rules="[{ required: true, message: '请选择是否公开', trigger: 'change' }]">
<el-radio-group v-model="form.isPublic">
<el-radio label="1"></el-radio>
<el-radio label="0"></el-radio>
</el-radio-group>
</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 () {
var regPhone = (rule, value, callback) => {
if (!value) {
return callback(new Error('请输入电话'))
} else {
const reg = /^[0-9]{3,11}$/
if (reg.test(value)) {
callback()
} else {
return callback(new Error('请输入正确的电话号码'))
}
}
}
return {
info: {},
form: {
areaId: '',
name: '',
areaName: '',
phone: '',
isPublic: '1',
type: '',
},
id: '',
regPhone,
}
},
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/appconvenientaddressbook/queryDetailById?id=${id}`).then(res => {
if (res?.data) {
this.form = res.data
}
})
},
onClose () {
this.form.explain = ''
},
confirm () {
this.$refs.CBookForm.validate((valid) => {
if (valid) {
this.instance.post(`/app/appconvenientaddressbook/addOrUpdate`, {
...this.form,
id: this.params.id || ''
}).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>

View File

@@ -0,0 +1,438 @@
<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>
<ai-import :instance="instance" :dict="dict" type="appconvenientaddressbook" name="便民通讯录"
@success="getList()">
<el-button icon="iconfont iconImport">导入</el-button>
</ai-import>
<ai-download :instance="instance" url="/app/appconvenientaddressbook/export" :params="search" fileName="便民通讯录"
:disabled="tableData.length == 0">
<el-button icon="iconfont iconExported" :disabled="tableData.length == 0">导出</el-button>
</ai-download>
</template>
<template slot="right">
<el-input
v-model="search.name"
class="search-input"
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"
style="margin-top: 6px;"
:current.sync="search.current"
:size.sync="search.size"
@getList="getList">
<el-table-column slot="isPublic" label="是否公开" align="center">
<template slot-scope="{ row }">
<el-switch
v-model="row.isPublic"
active-value="1"
@change="e => onChange(row.id, e)"
inactive-value="0">
</el-switch>
</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" @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,
name: '',
areaId: ''
},
defaultExpanded: [],
defaultChecked: [],
areaTree: [],
defaultProps: {
children: 'children',
label: 'name'
},
currIndex: -1,
total: 10,
colConfigs: [
{prop: 'name', label: '名称', align: 'left'},
{prop: 'type', label: '类型', align: 'center'},
{prop: 'phone', label: '电话', align: 'center'},
{prop: 'createTime', align: 'center', label: '创建时间'},
{slot: 'isPublic', label: '是否公开', align: 'center'}
],
areaName: '',
unitName: '',
tableData: []
}
},
computed: {
...mapState(['user']),
isShowAdd() {
return false
}
},
watch: {
unitName(val) {
this.$refs.tree.filter(val)
}
},
created() {
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/appconvenientaddressbook/list`, null, {
params: {
...this.search
}
}).then(res => {
if (res.code == 0) {
this.tableData = res.data.records
this.total = res.data.total
}
})
},
onChange(id) {
this.instance.post(`/app/appconvenientaddressbook/enable?id=${id}`).then(res => {
if (res.code == 0) {
this.$message.success('修改成功')
this.getList()
}
})
},
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/appconvenientaddressbook/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;
::v-deep input {
width: 100%;
}
}
.el-button {
width: 84px;
flex-shrink: 1;
margin-right: 8px;
}
}
span {
color: #222222;
font-size: 14px;
}
::v-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;
}
}
}
}
::v-deep .ai-list__content--left {
margin-right: 2px;
}
.villagecode-left {
width: 100%;
height: auto;
background: #FAFAFB;
.villagecode-left__title {
display: flex;
align-items: center;
height: 40px;
padding: 0 16px;
background: #fff;
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;
}
}
}
}
::v-deep .ai-list__content--right {
.ai-list__content--right-wrapper {
min-height: 100%;
}
}
}
.message-info__img {
font-size: 0;
width: 144px;
height: 144px;
}
</style>

View File

@@ -0,0 +1,87 @@
<template>
<ai-list class="AppDeviceConfig">
<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>
</template>
<script>
import eyeList from './components/eyeList.vue'
import videoList from './components/videoList.vue'
import { mapState } from 'vuex'
export default {
name: 'AppDeviceConfig',
label: '设备配置',
components: {
eyeList,
videoList,
},
props: {
instance: Function,
dict: Object,
permissions: Function
},
computed: {
...mapState(['user']),
tabs () {
const tabList = [
{label: '千里眼', name: 'eyeList', comp: eyeList, permission: ''},
{label: '视联网', name: 'videoList', comp: videoList, permission: ''}
]
return tabList
}
},
data () {
return {
currIndex: '0',
component: 'eyeList',
params: {},
areaId: '',
areaName: ''
}
},
created () {
this.areaId = this.user.info.areaId
},
methods: {
onChange (data) {
this.component = data.type
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>
.AppDeviceConfig {
height: 100%;
}
</style>

View File

@@ -0,0 +1,237 @@
<template>
<ai-list class="eyeList" isTabs>
<template slot="content">
<ai-search-bar bottomBorder>
<template #left>
<el-button type="primary" icon="iconfont iconAdd" size="small" @click="add('添加设备配置', {})">添加</el-button>
<el-button icon="el-icon-delete" class="delete-btn del-btn-list" :disabled="!ids.length" @click="remove(ids)">删除</el-button>
</template>
<template slot="right">
<el-input
v-model="search.condition"
class="search-input"
size="small"
v-throttle="() => {search.current = 1, getList()}"
placeholder="请输入CorpId"
clearable
@change="getList"
@clear="search.current = 1, search.condition = '', 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"
@selection-change="v=>ids=v.map(e=>e.id)">
<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="add('编辑设备配置', row)">编辑</el-button>
<el-button type="text" @click="refresh(row)">刷新</el-button>
<el-button type="text" @click="remove(row.id)">删除</el-button>
</div>
</template>
</el-table-column>
<el-table-column slot="flag" align="center" label="状态" width="100">
<template v-slot="{ row }">
<el-switch v-model="row.flag" @change="onChange(row)" active-value="1" inactive-value="0"
active-color="#5088FF" inactive-color="#D0D4DC"></el-switch>
</template>
</el-table-column>
</ai-table>
<ai-dialog :title="dialogTitle" :visible.sync="dialog" width="800px" @onConfirm="addForm" @closed="dialogForm={}">
<el-form ref="addForm" :model="dialogForm" :rules="rules" size="small" label-width="160px">
<el-form-item label="CorpId" prop="corpId">
<el-input v-model.trim="dialogForm.corpId" placeholder="请输入..." clearable :maxLength="50"/>
</el-form-item>
<el-form-item required label="状态">
<el-radio-group v-model="dialogForm.flag">
<el-radio :label="0">关闭</el-radio>
<el-radio :label="1">开启</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="AppId">
<el-input v-model.trim="dialogForm.appId" placeholder="请输入..." clearable :maxLength="50" />
</el-form-item>
<el-form-item label="RSA">
<el-input v-model.trim="dialogForm.rsa" placeholder="请输入..." clearable :maxLength="5000" type="textarea" :rows="5"/>
</el-form-item>
<el-form-item label="SECRET">
<el-input v-model.trim="dialogForm.secret" placeholder="请输入..." clearable :maxLength="50" />
</el-form-item>
<el-form-item label="TOKEN">
<el-input v-model.trim="dialogForm.token" placeholder="请输入..." clearable :maxLength="200" type="textarea" :rows="2"/>
</el-form-item>
<el-form-item label="结点ids">
<el-input v-model.trim="dialogForm.orgIds" placeholder="请输入..." clearable :maxLength="50" />
</el-form-item>
<el-form-item label="版本号">
<el-input v-model.trim="dialogForm.version" placeholder="请输入..." clearable :maxLength="50" />
</el-form-item>
<el-form-item label="大喇叭账号">
<el-input v-model.trim="dialogForm.dlbName" placeholder="请输入..." clearable :maxLength="50" />
</el-form-item>
<el-form-item label="大喇叭密码">
<el-input v-model.trim="dialogForm.dlbPwd" placeholder="请输入..." clearable :maxLength="50" />
</el-form-item>
<el-form-item label="大喇叭Token">
<el-input v-model.trim="dialogForm.dlbToken" placeholder="请输入..." clearable :maxLength="50" />
</el-form-item>
</el-form>
</ai-dialog>
</template>
</ai-list>
</template>
<script>
import { mapState } from 'vuex'
export default {
name: 'eyeList',
props: {
instance: Function,
dict: Object,
areaId: String
},
data () {
return {
search: {
current: 1,
condition: '',
size: 10,
},
ids: [],
tableData: [],
total: 0,
loading: false,
dialog: false,
dialogTitle: '',
dialogForm: {}
}
},
computed: {
...mapState(['user']),
param () {
return this.search
},
rules() {
return {
corpId: [{required: true, message: "请输入CorpId"}],
}
},
colConfigs() {
return [
{type: "selection"},
{ prop: 'corpId', label: 'CorpId', fixed: 'left', width: 220 },
{ slot: 'flag', align: 'center', label: '状态', fixed: 'left', width: 120 },
{ prop: 'appId', align: 'center', label: 'AppId', width: 240 },
{ prop: 'rsa', align: 'center', label: 'RSA', width: 240 },
{ prop: 'secret', align: 'center', label: 'SECRET', width: 180 },
{ prop: 'token', align: 'center', label: 'TOKEN', width: 120 },
{ prop: 'orgIds', align: 'center', label: '结点ids', width: 120 },
{ prop: 'version', align: 'center', label: '版本号', width: 120 },
{ prop: 'dlbName', align: 'center', label: '大喇叭账号', width: 140 },
{ prop: 'dlbPwd', align: 'center', label: '大喇叭密码', width: 140 },
{ prop: 'dlbToken', align: 'center', label: '大喇叭Token', width: 180 },
{ prop: 'createTime', align: 'center', label: '创建时间', fixed: 'right', width: 180 },
{ slot: 'options'},
]
}
},
created () {
this.getList()
},
methods: {
getListInit() {
this.search.current = 1
this.getList()
},
getList () {
this.instance.post(`/app/appzyaccountconfig/list`, null, {
params: {
...this.search,
type: 0
}
}).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
})
},
remove(id) {
this.$confirm('确定删除该数据?').then(() => {
this.instance.post(`/app/appzyaccountconfig/delete?ids=${id}`).then(res => {
if (res.code == 0) {
this.$message.success('删除成功!')
this.getList()
}
})
})
},
add(title, item) {
this.dialog = true
this.dialogTitle = title
this.dialogForm = item
if(title == '添加设备配置') {
this.dialogForm.flag = 1
this.dialogForm.version = '1.0.0'
}
},
addForm() {
this.$refs.addForm.validate((valid) => {
if (valid) {
this.dialogForm.type = 0
this.instance.post(`/app/appzyaccountconfig/addOrUpdate`, this.dialogForm).then((res) => {
if (res.code == 0) {
this.$message.success(`${this.dialogForm.id ? '编辑成功' : '添加成功'}`)
this.getListInit()
this.dialog = false;
}
});
} else {
return false;
}
});
},
refresh(row) {
this.$confirm('确定刷新该数据token').then(() => {
this.instance.post(`/app/appzyaccountconfig/initQlyToken?id=${row.id}`).then(res => {
if (res.code == 0) {
this.$message.success('刷新成功!')
this.getList()
}
})
})
},
onChange(row) {
this.instance.post(`/app/appzyaccountconfig/setFlag`, null, {
params: {
id: row.id,
flag: row.flag
}
}).then((res) => {
if (res.code == 0) {
this.$message.success(+row.flag ? '已启用' : '已禁用');
this.getList();
}
})
},
}
}
</script>

View File

@@ -0,0 +1,224 @@
<template>
<ai-list class="videoList" isTabs>
<template slot="content">
<ai-search-bar bottomBorder>
<template #left>
<el-button type="primary" icon="iconfont iconAdd" size="small" @click="add('添加设备配置', {})">添加</el-button>
<el-button icon="el-icon-delete" class="delete-btn del-btn-list" :disabled="!Boolean(ids.length)" @click="remove(ids)">删除</el-button>
</template>
<template #right>
<el-input
v-model="search.condition"
class="search-input"
size="small"
v-throttle="() => {search.current = 1, getList()}"
placeholder="请输入CorpId"
clearable
@change="getList"
@clear="search.current = 1, search.condition = '', 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"
@selection-change="v=>ids=v.map(e=>e.id)">
<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="add('编辑设备配置', row)">编辑</el-button>
<el-button type="text" @click="refresh(row)">刷新</el-button>
<el-button type="text" @click="remove(row.id)">删除</el-button>
</div>
</template>
</el-table-column>
<el-table-column slot="flag" align="center" label="状态" width="100">
<template v-slot="{ row }">
<el-switch v-model="row.flag" @change="onChange(row)" active-value="1" inactive-value="0"
active-color="#5088FF" inactive-color="#D0D4DC"></el-switch>
</template>
</el-table-column>
</ai-table>
<ai-dialog :title="dialogTitle" :visible.sync="dialog" width="800px" @onConfirm="addForm" @closed="dialogForm={}">
<el-form ref="addForm" :model="dialogForm" :rules="rules" size="small" label-width="160px">
<el-form-item label="CorpId" prop="corpId">
<el-input v-model.trim="dialogForm.corpId" placeholder="请输入..." clearable :maxLength="50"/>
</el-form-item>
<el-form-item required label="状态">
<el-radio-group v-model="dialogForm.flag">
<el-radio :label="0">关闭</el-radio>
<el-radio :label="1">开启</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="用户ID">
<el-input v-model.trim="dialogForm.slwUserId" placeholder="请输入..." clearable :maxLength="50" />
</el-form-item>
<el-form-item label="地区编码">
<el-input v-model.trim="dialogForm.slwAreaId" placeholder="请输入..." clearable :maxLength="50" />
</el-form-item>
<el-form-item label="TOKEN">
<el-input v-model.trim="dialogForm.slwToken" placeholder="请输入..." clearable :maxLength="50" />
</el-form-item>
<el-form-item label="大喇叭账号">
<el-input v-model.trim="dialogForm.dlbName" placeholder="请输入..." clearable :maxLength="50" />
</el-form-item>
<el-form-item label="大喇叭密码">
<el-input v-model.trim="dialogForm.dlbPwd" placeholder="请输入..." clearable :maxLength="50" />
</el-form-item>
<el-form-item label="大喇叭Token">
<el-input v-model.trim="dialogForm.dlbToken" placeholder="请输入..." clearable :maxLength="50" />
</el-form-item>
</el-form>
</ai-dialog>
</template>
</ai-list>
</template>
<script>
import { mapState } from 'vuex'
export default {
name: 'eyeList',
props: {
instance: Function,
dict: Object,
areaId: String
},
data () {
return {
search: {
current: 1,
condition: '',
size: 10,
},
ids: [],
tableData: [],
total: 0,
loading: false,
dialog: false,
dialogTitle: '',
dialogForm: {}
}
},
computed: {
...mapState(['user']),
param () {
return this.search
},
rules() {
return {
corpId: [{required: true, message: "请输入CorpId"}],
}
},
colConfigs() {
return [
{type: "selection"},
{ prop: 'corpId', label: 'CorpId', fixed: 'left', width: 220 },
{ slot: 'flag', align: 'center', label: '状态', fixed: 'left', width: 120 },
{ prop: 'slwUserId', align: 'center', label: '用户ID', width: 180 },
{ prop: 'slwAreaId', align: 'center', label: '地区编码', width: 180 },
{ prop: 'slwToken', align: 'center', label: 'TOKEN', width: 220 },
{ prop: 'dlbName', align: 'center', label: '大喇叭账号', width: 140 },
{ prop: 'dlbPwd', align: 'center', label: '大喇叭密码', width: 140 },
{ prop: 'dlbToken', align: 'center', label: '大喇叭Token', width: 180 },
{ prop: 'createTime', align: 'center', label: '创建时间', width: 180 },
{ slot: 'options'},
]
}
},
created () {
this.getList()
},
methods: {
getListInit() {
this.search.current = 1
this.getList()
},
getList () {
this.instance.post(`/app/appzyaccountconfig/list`, null, {
params: {
...this.search,
type: 1
}
}).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
})
},
remove(id) {
this.$confirm('确定删除该数据?').then(() => {
this.instance.post(`/app/appzyaccountconfig/delete?ids=${id}`).then(res => {
if (res.code == 0) {
this.$message.success('删除成功!')
this.getList()
}
})
})
},
add(title, item) {
this.dialog = true
this.dialogTitle = title
this.dialogForm = item
if(title == '添加设备配置') {
this.dialogForm.flag = 1
}
},
addForm() {
this.$refs.addForm.validate((valid) => {
if (valid) {
this.dialogForm.type = 1
this.instance.post(`/app/appzyaccountconfig/addOrUpdate`, this.dialogForm).then((res) => {
if (res.code == 0) {
this.$message.success(`${this.dialogForm.id ? '编辑成功' : '添加成功'}`)
this.getListInit()
this.dialog = false;
}
});
} else {
return false;
}
});
},
refresh(row) {
this.$confirm('确定刷新该数据token').then(() => {
this.instance.post(`/app/appzyaccountconfig/initSlwToken?id=${row.id}`).then(res => {
if (res.code == 0) {
this.$message.success('刷新成功!')
this.getList()
}
})
})
},
onChange(row) {
this.instance.post(`/app/appzyaccountconfig/setFlag`, null, {
params: {
id: row.id,
flag: row.flag
}
}).then((res) => {
if (res.code == 0) {
this.$message.success(+row.flag ? '已启用' : '已禁用');
this.getList();
}
})
}
}
}
</script>

View File

@@ -0,0 +1,62 @@
<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>

View File

@@ -0,0 +1,316 @@
<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', formart: 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>

View File

@@ -0,0 +1,293 @@
<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: '健康码', formart: v => v ? this.dict.getLabel('epidemicHealthCode', v) : '-' },
{ prop: 'checkTime', align: 'center', label: '核酸日期', formart: v => v ? v.split(' ')[0] : '-' },
{ prop: 'checkResult', align: 'center', label: '检测结果', formart: 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: '今日上报', formart: 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 {
::v-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>

View File

@@ -0,0 +1,54 @@
<template>
<section class="AppReportAtWill">
<component ref="component" :is="currentPage" @change="onChange" :params="params" :instance="instance" :dict="dict"/>
</section>
</template>
<script>
import List from './components/List'
import Detail from './components/Detail'
import Setting from './components/Setting'
export default {
name: 'AppReportAtWill',
label: '随手拍',
props: {
instance: Function,
dict: Object
},
data() {
return {
component: 'List',
params: {}
}
},
computed: {
currentPage() {
let {hash, query: {id}} = this.$route
return hash == "#Setting" ? Setting :
!!id ? Detail : List
}
},
components: {
List,
Detail,
Setting
},
methods: {
onChange(data) {
this.$router.push({query: data.params, hash: data.type == "Setting" ? "#Setting" : ""})
}
}
}
</script>
<style lang="scss">
.AppReportAtWill {
height: 100%;
background: #F3F6F9;
overflow: auto;
}
</style>

View File

@@ -0,0 +1,572 @@
<template>
<ai-detail class="reportAtWillDetail" v-loading="isLoading">
<template #title>
<ai-title title="随手拍详情" isShowBack isShowBottomBorder @onBackClick="cancel(false)">
<template #rightBtn>
<div class="title-btns">
<el-button type="primary" icon="iconfont iconPerson_Transfered" @click="isShowForward = true" v-if="detail.eventStatus < 2">指派事件</el-button>
<el-button type="primary" icon="iconfont iconRegister" @click="isShowAdd = true" v-if="detail.eventStatus < 2">处理事件</el-button>
</div>
</template>
</ai-title>
</template>
<template #content>
<div class="detail-content__wrapper">
<ai-card class="detail-content__wrapper--left" title="基础信息">
<template #content>
<ai-wrapper>
<ai-info-item label="上报人员" :value="detail.name"></ai-info-item>
<ai-info-item label="当前状态" :value="dict.getLabel('clapEventStatus', detail.eventStatus)"></ai-info-item>
<ai-info-item label="联系方式">{{ detail.phone }}</ai-info-item>
<ai-info-item label="上报时间">{{ detail.createTime }}</ai-info-item>
<ai-info-item label="事件类型">{{ detail.groupName }}</ai-info-item>
<ai-info-item label="事件描述" isLine>{{ detail.content }}</ai-info-item>
<ai-info-item label="现场照片" isLine>
<ai-uploader :instance="instance" disabled v-model="detail.files"></ai-uploader>
</ai-info-item>
<ai-info-item label="所属网格">{{ detail.girdName }}</ai-info-item>
<ai-info-item label="事件位置" isLine>
<div id="map" style="width: 500px; height: 280px;"></div>
</ai-info-item>
</ai-wrapper>
</template>
</ai-card>
<div class="rightZone">
<ai-card title="办理进度">
<template #content>
<el-steps direction="vertical" :active="1">
<el-step
v-for="(item, i) in processList"
:key="i"
:title="item.systemExplain"
:description="item.doTime">
<template #title>
<h2 class="step-title" style="font-weight: 500; font-size: 14px;">
{{ item.systemExplain }}
</h2>
</template>
<template #description>
<p style="color: #888; margin: 0 4px 10px 0; font-size: 14px;">{{ item.doTime }}</p>
<div style="color: #444;margin-bottom: 10px;" v-if="item.doExplain">{{ item.doExplain }}</div>
<ai-uploader :instance="instance" disabled v-model="item.files"></ai-uploader>
</template>
</el-step>
</el-steps>
</template>
</ai-card>
</div>
</div>
<ai-dialog
:visible.sync="isShowAdd"
width="800px"
title="事件处理"
@closed="onClose"
@onConfirm="handleEvent">
<el-form class="ai-form" label-width="120px" :model="form" ref="form">
<el-form-item label="事件分类" prop="groupId" style="width: 100%;" :rules="[{ required: true, message: '请选择事件分类' }]">
<ai-select
v-model="form.groupId"
placeholder="请选择事件分类"
:selectList="dictList">
</ai-select>
</el-form-item>
<el-form-item label="处理结果" prop="eventStatus" style="width: 100%;" :rules="[{ required: true, message: '请选择处理结果' }]">
<el-radio-group v-model="form.eventStatus">
<el-radio label="2">已办结</el-radio>
<el-radio label="3">已拒绝</el-radio>
</el-radio-group>
</el-form-item>
<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-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>
<ai-dialog
:visible.sync="isShowForward"
width="800px"
@close="onClose"
title="事件指派"
@onConfirm="onForwardConfirm">
<el-form class="ai-form" label-width="120px" :model="forwardForm" ref="forwardForm">
<el-form-item label="转交" prop="name" style="width: 100%;" :rules="[{ required: true, message: '请选择网格员或网格' }]">
<el-input disabled size="small" v-model="forwardForm.name" clearable placeholder="请选择网格员或网格">
<template slot="append">
<el-button @click="getGirdList().then(()=>isShowUser=true )">选择</el-button>
</template>
</el-input>
</el-form-item>
<el-form-item label="办理意见" prop="content" style="width: 100%;" :rules="[{ required: true, message: '请输入办理意见' }]">
<el-input type="textarea" :rows="5" :maxlength="500" v-model="forwardForm.content" clearable placeholder="请输入办理意见" show-word-limit></el-input>
</el-form-item>
<el-form-item label="图片" prop="files" style="width: 100%;">
<ai-uploader
:instance="instance"
v-model="forwardForm.files"
isShowTip
:limit="9">
</ai-uploader>
</el-form-item>
</el-form>
</ai-dialog>
<ai-dialog
:visible.sync="isShowUser"
width="800px"
title="选择网格或网格员"
@onConfirm="onConfirm">
<div class="grid-wrapper">
<el-input
style="margin-bottom: 10px;"
size="small"
placeholder="请输入网格名称/网格员姓名/网格员电话"
v-model="name" @change="$refs.tree.filter(name)"
suffix-icon="iconfont iconSearch">
</el-input>
<el-tree
:filter-node-method="filterNode"
ref="tree"
:props="defaultProps"
node-key="id"
:data="tree"
highlight-current
@current-change="onTreeChange">
<div class="tree-container" slot-scope="{ data }">
<div class="tree-container__user">
<div class="tree-user__item">
<span>{{ data.isUser ? `${data.name}-${data.phone}` : data.girdName }}</span>
</div>
</div>
</div>
</el-tree>
</div>
</ai-dialog>
</template>
</ai-detail>
</template>
<script>
import AMapLoader from '@amap/amap-jsapi-loader'
import {mapState} from 'vuex'
export default {
name: 'Detail',
props: ['dict', 'instance'],
data() {
return {
forwardForm: {
content: '',
girdId: '',
girdName: '',
girdMemberId: '',
girdMemberName: '',
name: ''
},
isLoading: true,
name: '',
detail: {},
isShowUser: false,
eventList: [],
isShowAdd: false,
userList: [],
processList: [],
dictList: [],
defaultProps: {
label: 'girdName'
},
isShowForward: false,
tree: [],
gridInfo: {},
form: {
files: [],
groupId: '',
groupName: '',
content: [],
eventStatus: '2'
}
}
},
computed: {
...mapState(['user'])
},
created() {
this.getDict()
this.dict.load('clapEventStatus').then(() => {
this.getDetail()
})
},
methods: {
getDetail() {
this.instance.post('/app/appclapeventinfo/queryDetailById', null, {
params: {id: this.$route.query.id}
}).then(res => {
if (res?.data) {
this.detail = res.data
this.processList = res.data.processList
this.form.groupId = res.data.groupId
this.$nextTick(() => {
this.initMap()
})
this.isLoading = false
}
}).catch(() => {
this.isLoading = false
})
},
getGirdList() {
return this.instance.post(`/app/appgirdinfo/listAllByTop`).then(res => {
if (res?.data) {
return this.tree = this.formatList([res.data])
}
})
},
onClose() {
this.form.files = []
this.form.groupId = ''
this.form.groupName = ''
this.form.content = ''
this.form.eventStatus = ''
this.forwardForm.content = ''
this.forwardForm.girdId = ''
this.forwardForm.girdName = ''
this.forwardForm.girdMemberId = ''
this.forwardForm.girdMemberName = ''
this.forwardForm.name = ''
},
formatList(list) {
for (let item of list) {
item.children = [item.girdList, item.girdMemberList?.map(e => ({
...e, isUser: true, girdName: item.girdName,
girdId: item.id
})) || []].flat()
if (item.girdList?.length > 0) {
this.formatList(item.girdList)
}
}
return list
},
filterNode(value, data) {
if (!value) return true
return (data.girdName && data.girdName.indexOf(value) !== -1) || (data.name && data.name.indexOf(value) !== -1) || (data.name && data.phone.indexOf(value) !== -1)
},
onTreeChange(e) {
this.gridInfo = e
},
onForwardConfirm() {
this.$refs.forwardForm.validate(v => {
if (v) {
this.instance.post('/app/appclapeventinfo/transferByManager', {
...this.forwardForm,
id: this.$route.query.id
}).then(res => {
if (res?.code == 0) {
this.isShowForward = false
this.getDetail()
this.$message.success('转交成功!')
}
})
}
})
},
onConfirm() {
if (this.gridInfo.userId) {
this.forwardForm.girdId = this.gridInfo.girdId
this.forwardForm.girdName = this.gridInfo.girdName
this.forwardForm.girdMemberId = this.gridInfo.id
this.forwardForm.girdMemberName = this.gridInfo.name
} else {
this.forwardForm.girdId = this.gridInfo.id
}
this.forwardForm.girdName = this.gridInfo.girdName
this.forwardForm.name = `${this.gridInfo.girdName}${this.gridInfo.name ? '-' + this.gridInfo.name : ''}`
this.isShowUser = false
},
getDict() {
this.instance.post(`/app/appclapeventgroup/list?current=1&size=100000`).then(res => {
if (res.code == 0) {
this.dictList = res.data.records.map(v => {
return {
dictValue: v.id,
dictName: v.groupName
}
})
}
})
},
close() {
this.$confirm('确定关闭该事件?').then(() => {
this.instance.post(`/app/appmininotice/delete?ids=${this.$route.query.id}`).then(res => {
if (res.code == 0) {
this.$message.success('删除成功!')
this.getList()
}
})
})
},
cancel(isRefresh) {
this.$emit('change', {
type: 'list',
isRefresh: !!isRefresh
})
},
onChange(e) {
this.instance.post(`/app/appvillagerintegralrule/list?size=1000&classification=${e}&ruleStatus=1`).then(res => {
if (res.code === 0) {
this.form.ruleId = ''
this.eventList = res.data.records
}
})
},
initMap() {
let {lng, lat} = this.detail
let center = [lng, lat]
AMapLoader.load({
key: 'b553334ba34f7ac3cd09df9bc8b539dc',
version: '2.0'
}).then(AMap => {
let map = new AMap.Map('map', {
center,
zoom: 14
})
let marker = new AMap.Marker({
position: new AMap.LngLat(lng, lat),
title: this.detail.address
})
map.add(marker)
})
},
handleEvent() {
this.$refs.form.validate(v => {
if (v) {
this.instance.post('/app/appclapeventinfo/finishByManager', {
...this.form,
groupName: this.dictList.filter(v => v.dictValue === this.form.groupId)[0].dictName,
id: this.$route.query.id
}).then(res => {
if (res?.code == 0) {
this.isShowAdd = false
this.getDetail()
this.$message.success('处理成功!')
}
})
}
})
}
}
}
</script>
<style lang="scss" scoped>
.reportAtWillDetail {
height: 100%;
.grid-wrapper {
min-height: 360px;
}
.title-btns {
display: flex;
align-items: center;
}
::v-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;
}
}
}
.el-steps {
::v-deep .el-step__icon {
font-size: 12px;
color: #555555;
border-color: #d0d4dc;
}
::v-deep .el-step__head.is-finish {
.el-step__icon.is-text {
border: none;
color: #fff;
font-size: 12px;
background: #2266ff;
}
}
::v-deep .el-step__line {
background-color: #d0d4dc;
}
}
.imgs {
font-size: 0;
img {
width: 108px;
height: 108px;
margin-right: 4px;
margin-bottom: 4px;
cursor: pointer;
user-select: none;
&:hover {
opacity: 0.8;
}
&:nth-of-type(2n) {
margin-right: 0;
}
}
}
::v-deep .report-dialog {
.el-select {
width: 100%;
}
}
::v-deep .el-step__head.is-process {
color: #555;
border-color: #555;
}
::v-deep .is-finish h2 {
color: #2266ff;
}
.step-title {
color: #555;
}
.detail-content__wrapper {
display: flex;
width: 100%;
.detail-content__wrapper--left {
flex: 1;
margin-right: 20px;
}
}
::v-deep .ai-detail__content {
background: #f3f6f9;
.ai-detail__content--wrapper {
display: flex;
gap: 16px;
width: 100%;
max-width: 100%;
padding: 16px;
box-sizing: border-box;
& > .el-card {
flex: 1;
min-width: 0;
}
.rightZone {
width: 400px;
flex-shrink: 0;
display: flex;
flex-direction: column;
gap: 16px;
}
}
}
::v-deep .el-card {
.el-card__header {
padding: 12px 16px;
font-weight: bold;
}
.el-card__body {
padding: 8px;
}
#amap {
width: 466px;
height: 232px;
}
.el-steps {
margin-left: 8px;
}
.imgFormItem > .el-form-item__content {
display: flex;
gap: 16px;
flex-wrap: wrap;
&:before {
content: none;
}
.el-image__inner {
width: 82px;
height: 82px;
}
}
}
}
</style>

View File

@@ -0,0 +1,149 @@
<template>
<ai-list>
<template #title>
<ai-title title="随手拍" isShowBottomBorder>
<el-button type="primary" slot="rightBtn" @click="toSetting">设置</el-button>
</ai-title>
</template>
<template #content>
<ai-search-bar>
<template #left>
<ai-select
v-model="search.eventStatus"
clearable
placeholder="处理状态"
:selectList="dict.getDict('clapEventStatus')"
@change="search.current = 1, getList()">
</ai-select>
</template>
<template #right>
<el-input
v-model="search.content"
class="search-input"
size="small"
v-throttle="() => {search.current = 1, getList()}"
placeholder="请输入内容描述/上报居民/联系方式"
clearable
@change="getList"
@clear="search.current = 1, search.content = '', getList()"
suffix-icon="iconfont iconSearch">
</el-input>
</template>
</ai-search-bar>
<ai-table :tableData="tableData" :colConfigs="colConfigs" :total="total" :current.sync="search.current" :size.sync="search.size" @getList="getList">
<el-table-column slot="options" label="操作" fixed="right" width="120" align="center">
<div class="table-options" slot-scope="{row}">
<el-button type="text" title="详情" @click="toDetail(row.id)">详情</el-button>
<el-button type="text" title="删除" @click="handleDelete(row.id)">删除</el-button>
</div>
</el-table-column>
</ai-table>
</template>
</ai-list>
</template>
<script>
import {mapState} from 'vuex'
export default {
name: 'List',
label: "随手拍",
props: {
instance: Function,
dict: Object
},
data() {
return {
userList: [],
search: {
current: 1,
size: 10,
eventStatus: '',
content: ''
},
total: 0,
tableData: [],
content: '',
id: ''
}
},
computed: {
...mapState(['user']),
colConfigs() {
return [
{prop: 'content', label: '内容描述', width: '300px'},
{prop: 'groupName', label: '事件类型', align: 'center'},
{prop: 'girdName', label: '所属网格', align: 'center'},
{prop: 'createTime', label: '上报时间', align: 'center'},
{prop: 'name', label: '上报居民', align: 'center'},
{prop: 'phone', label: '联系方式', align: 'center'},
{prop: 'eventStatus', label: '处理状态', align: 'center', formart: v => this.dict.getLabel('clapEventStatus', v)},
{prop: 'processTime', label: '处理时长', align: 'center'},
{slot: 'options'}
]
},
handleStatusOps() {
return this.dict.getDict("reportAtWillHandleStatus").map(e => ({label: e.dictName, value: e.dictValue}))
}
},
created() {
this.dict.load('clapEventStatus').then(() => {
this.getList()
})
},
methods: {
getList() {
this.instance.post(`/app/appclapeventinfo/list`, null, {
params: {
...this.search
}
}).then(res => {
if (res.code == 0) {
this.tableData = res.data.records
this.total = res.data.total
}
})
},
toDetail(id) {
this.$emit('change', {
type: 'Detail',
params: {
id: id || ''
}
})
},
toSetting() {
this.$emit('change', {
type: 'Setting',
params: {
id: ''
}
})
},
handleDelete(ids) {
this.$confirm("是否要进行删除?").then(() => {
this.instance.post("/app/appclapeventinfo/delete", null, {
params: {ids}
}).then(res => {
if (res?.code == 0) {
this.$message.success("删除成功!")
this.getList()
}
})
}).catch(() => 0)
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,178 @@
<template>
<ai-list class="notice">
<template slot="title">
<ai-title isShowBack isShowBottomBorder title="事件类型" @onBackClick="cancel(false)"></ai-title>
</template>
<template slot="content">
<ai-search-bar class="search-bar">
<template #left>
<el-button size="small" type="primary" icon="iconfont iconAdd" @click="isShowAdd = true">添加事件类型</el-button>
</template>
<template slot="right">
<el-input
v-model="search.groupName"
class="search-input"
size="small"
v-throttle="() => {search.current = 1, getList()}"
placeholder="请输入事件类型名称"
clearable
@change="getList"
@clear="search.current = 1, search.groupName = '', 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="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="120px" fixed="right" label="操作" align="center">
<div class="table-options" slot-scope="{ row }">
<el-button type="text" @click="edit(row)">编辑</el-button>
<el-button type="text" @click="remove(row.id)">删除</el-button>
</div>
</el-table-column>
</ai-table>
<ai-dialog
:visible.sync="isShowAdd"
width="780px"
height="580px"
:title="id ? '编辑事件类型' : '添加事件类型'"
@close="onClose"
@onConfirm="onConfirm">
<el-form ref="form" class="ai-form" :model="form" label-width="110px" label-position="right">
<el-form-item label="事件类型" prop="groupName" style="width: 100%;" :rules="[{ required: true, message: '请输入事件类型名称', trigger: 'blur' }]">
<el-input size="small" :maxlength="10" show-word-limit placeholder="请输入事件类型名称" v-model="form.groupName"></el-input>
</el-form-item>
<el-form-item label="排序" prop="showIndex" style="width: 100%;" :rules="[{ required: true, message: '请输入排序', trigger: 'blur' }]">
<el-input-number size="small" v-model="form.showIndex" :min="1" :max="100" label="请输入排序"></el-input-number>
</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 {
search: {
current: 1,
size: 10,
groupName: ''
},
form: {
groupName: '',
showIndex: ''
},
id: '',
isShowAdd: false,
total: 0,
colConfigs: [
{prop: 'groupName', label: '事件类型', align: 'left'},
{prop: 'showIndex', label: '排序', align: 'center'},
{slot: 'options', label: '操作'}
],
tableData: []
}
},
computed: {
...mapState(['user'])
},
mounted() {
this.getList()
},
methods: {
getList() {
this.instance.post(`/app/appclapeventgroup/list`, null, {
params: {
...this.search
}
}).then(res => {
if (res.code == 0) {
this.tableData = res.data.records
this.total = res.data.total
}
})
},
edit (e) {
this.id = e.id
this.form.groupName = e.groupName
this.form.showIndex = ''
this.$nextTick(() => {
this.isShowAdd = true
})
},
onClose () {
this.id = ''
this.form.showIndex = ''
this.form.groupName = ''
},
onConfirm () {
this.$refs.form.validate((valid) => {
if (valid) {
this.instance.post(`/app/appclapeventgroup/addOrUpdate`, {
...this.form,
id: this.id || null
}).then(res => {
if (res.code === 0) {
this.$message.success('添加成功')
this.isShowAdd = false
this.getList()
}
})
}
})
},
cancel (isRefresh) {
this.$emit('change', {
type: 'list',
isRefresh: !!isRefresh
})
},
remove(id) {
this.$confirm('确定删除该数据?').then(() => {
this.instance.post(`/app/appclapeventgroup/delete?ids=${id}`).then(res => {
if (res.code == 0) {
this.$message.success('删除成功!')
this.getList()
}
})
})
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,105 @@
<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>

View File

@@ -0,0 +1,200 @@
<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: '出发时间', formart: v => v.substr(0, v.length - 3) },
{
prop: 'startAreaName',
align: 'center',
label: '出发地区'
},
{ prop: 'arriveTime', align: 'center', label: '到达时间', formart: v => v.substr(0, v.length - 3) },
{
prop: 'arriveAreaName',
align: 'center',
label: '到达地区'
},
{ prop: 'checkTime', align: 'center', label: '核酸日期', formart: 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>

View File

@@ -0,0 +1,279 @@
<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 ? 'color:#42D784;' : 'color:#f46;'">{{dict.getLabel('epidemicMemberType', 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('epidemicMemberType', 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', 'epidemicMemberType', '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>

View File

@@ -0,0 +1,273 @@
<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: '出发时间', formart: v => v.substr(0, v.length - 3) },
{
prop: 'startAreaName',
align: 'center',
label: '出发地区'
},
{ prop: 'arriveTime', align: 'center', label: '到达时间', formart: v => v.substr(0, v.length - 3) },
{
prop: 'arriveAreaName',
align: 'center',
label: '到达地区'
},
{ prop: 'checkTime', align: 'center', label: '核酸日期', formart: 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 {
::v-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>

View File

@@ -0,0 +1,65 @@
<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>

View File

@@ -0,0 +1,154 @@
<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>

View File

@@ -0,0 +1,141 @@
<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', formart: 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>

View File

@@ -0,0 +1,205 @@
<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";
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, this.idCardNoUtil.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%;
::v-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;
}
}
::v-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>

View File

@@ -0,0 +1,235 @@
<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";
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 (this.idCardNoUtil.checkIdCardNo(code)) {
let info = this.idCardNoUtil.getIdCardInfo(code)
this.form.sex = this.dict.getValue('sex', info.gender)
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%;
::v-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%;
}
}
::v-deep .el-button {
.iconfont {
color: inherit
}
}
}
</style>

View File

@@ -0,0 +1,111 @@
<template>
<ai-list v-if="!isShowDetail">
<template slot="title">
<ai-title title="居民活动" :isShowBottomBorder="false" :isShowArea="currIndex === '0'" :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>
<Add v-else-if="componentName === 'Add'" :areaName="areaName" :areaId="areaId" :params="params" :instance="instance" :dict="dict" :permissions="permissions" @change="onChange"></Add>
<Detail v-else-if="componentName === 'Detail'" :params="params" :instance="instance" :dict="dict" :permissions="permissions" @change="onChange"></Detail>
</template>
<script>
import List from './components/List.vue'
import Statistics from './components/Statistics'
import Add from './components/Add'
import Detail from './components/Detail'
import { mapState } from 'vuex'
export default {
name: 'AppVillageActivity',
label: '居民活动',
components: {
List,
Add,
Detail,
Statistics
},
props: {
instance: Function,
dict: Object,
permissions: Function
},
computed: {
...mapState(['user']),
tabs () {
const tabList = [
{label: '活动管理', name: 'List', comp: List, permission: ''},
{label: '报到数据', name: 'Statistics', comp: Statistics, permission: ''}
].filter(item => {
return true
})
return tabList
}
},
data () {
return {
activeName: 'JoinEvent',
currIndex: '0',
componentName: '',
params: {},
areaName: '',
areaId: '',
isShowDetail: false
}
},
created () {
this.areaId = this.user.info.areaId
if (this.$route.query.id) {
this.componentName = this.$route.query?.type
this.params = {id: this.$route.query?.id}
this.isShowDetail = true
}
},
methods: {
onAreaChange () {
if (this.currIndex === '0') {
this.$nextTick(() => {
this.$refs[this.currIndex][0].getList()
})
}
},
onChange (data) {
if (data.type === 'list') {
this.componentName = 'List'
this.isShowDetail = false
this.params = data.params
}
if (data.type === 'Detail') {
this.componentName = 'Detail'
this.isShowDetail = true
this.params = data.params
}
if (data.type === 'Add') {
this.componentName = 'Add'
this.isShowDetail = true
this.params = data.params
}
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,166 @@
<template>
<ai-detail>
<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 label="活动标题" style="width: 100%;" prop="title" :rules="[{required: true, message: '请输入活动标题', trigger: 'blur'}]">
<el-input type="input" size="small" v-model="form.title" clearable placeholder="请输入活动标题..." maxlength="60" show-word-limit></el-input>
</el-form-item>
<el-form-item prop="areaId" style="width: 100%;" label="发布地区" :rules="[{required: true, message: '请选择发布地区', trigger: 'change'}]">
<ai-area-select @fullname="e => form.areaName = e" clearable always-show :instance="instance" v-model="form.areaId" :disabled-level="disabledLevel"></ai-area-select>
</el-form-item>
<el-form-item prop="beginTime" label="活动开始时间" :rules="[{required: true, message: '活动开始时间', trigger: 'change'}]">
<el-date-picker
style="width: 100%"
v-model="form.beginTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
size="small"
placeholder="活动开始时间">
</el-date-picker>
</el-form-item>
<el-form-item prop="endTime" label="活动结束时间" :rules="[{required: true, message: '活动结束时间', trigger: 'change'}]">
<el-date-picker
v-model="form.endTime"
style="width: 100%"
type="datetime"
size="small"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="活动开始时间">
</el-date-picker>
</el-form-item>
<el-form-item label="活动地点" style="width: 100%;" prop="address" :rules="[{required: true, message: '请输入活动地点题', trigger: 'blur'}]">
<el-input type="input" size="small" v-model="form.address" clearable placeholder="请输入活动地点题" maxlength="30" show-word-limit></el-input>
</el-form-item>
<el-form-item label="联系人" prop="contactPerson" :rules="[{required: true, message: '请输入联系人', trigger: 'blur'}]">
<el-input type="input" size="small" v-model="form.contactPerson" clearable placeholder="请输入联系人" maxlength="30" show-word-limit></el-input>
</el-form-item>
<el-form-item label="联系电话" prop="contactPhone" :rules="[{required: true, message: '请输入联系电话', trigger: 'blur'}]">
<el-input type="input" size="small" v-model="form.contactPhone" clearable placeholder="请输入联系电话" maxlength="30" show-word-limit></el-input>
</el-form-item>
<el-form-item label="活动介绍" style="width: 100%;" prop="content" :rules="[{required: true, message: '请输入内容', trigger: 'change'}]">
<ai-editor v-model="form.content" :instance="instance"/>
</el-form-item>
<el-form-item label="缩略图" style="width: 100%;" prop="url" :rules="[{required: true, message: '请上传缩略图', trigger: 'change'}]">
<ai-uploader
:instance="instance"
isShowTip
v-model="form.url"
: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>
import { mapState } from 'vuex'
export default {
name: 'Add',
props: {
instance: Function,
dict: Object,
params: Object,
areaId: String,
areaName: String
},
data () {
return {
info: {},
form: {
title: '',
content: '',
areaId: '',
areaName: '',
beginTime: '',
endTime: '',
address: '',
contactPerson: '',
contactPhone: '',
url: []
},
id: ''
}
},
computed: {
...mapState(['user'])
},
created () {
this.form.areaId = this.areaId
this.form.areaName = this.areaName
this.disabledLevel = this.user.info.areaList.length
if (this.params && this.params.id) {
this.id = this.params.id
this.getInfo(this.params.id)
}
},
methods: {
getInfo (id) {
this.instance.post(`/app/appvillageactivityinfo/queryDetailById?id=${id}`).then(res => {
if (res.code === 0) {
this.form = res.data
this.form.url = res.data.url ? JSON.parse(res.data.url) : []
}
})
},
confirm () {
this.$refs.form.validate((valid) => {
if (valid) {
const nowTime = new Date().getTime()
const beginTime = new Date(this.form.beginTime).getTime()
const endTime = new Date(this.form.endTime).getTime()
if (beginTime < nowTime) {
return this.$message.error('活动开始时间不能早于当前时间')
}
if (endTime < beginTime) {
return this.$message.error('活动结束时间不能早于活动开始时间')
}
this.instance.post(`/app/appvillageactivityinfo/addOrUpdate`, {
...this.form,
url: this.form.url.length ? JSON.stringify([{
url: this.form.url[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>

View File

@@ -0,0 +1,136 @@
<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>
<ai-card title="基本信息" v-show="currIndex === 0">
<template #content>
<ai-wrapper
label-width="120px">
<ai-info-item label="活动标题" isLine :value="info.title"></ai-info-item>
<ai-info-item label="发布地区" isLine :value="info.areaName"></ai-info-item>
<ai-info-item label="活动开始时间" :value="info.beginTime"></ai-info-item>
<ai-info-item label="活动结束时间" :value="info.endTime"></ai-info-item>
<ai-info-item label="活动地点" isLine :value="info.address"></ai-info-item>
<ai-info-item label="联系人" :value="info.contactPerson"></ai-info-item>
<ai-info-item label="联系电话" :value="info.contactPhone"></ai-info-item>
<ai-info-item label="活动介绍" isLine>
<AiArticle :value="info.content"></AiArticle>
</ai-info-item>
<ai-info-item label="缩略图">
<ai-uploader
:instance="instance"
disabled
v-model="info.url"
:limit="1">
</ai-uploader>
</ai-info-item>
</ai-wrapper>
</template>
</ai-card>
<ai-card title="报名情况" v-show="currIndex === 1">
<template #content>
<ai-table
class="detail-table__table"
:border="true"
:tableData="tableData"
:col-configs="colConfigs"
:total="total"
:current.sync="search.current"
:size.sync="search.size"
:stripe="false"
@getList="getList">
</ai-table>
</template>
</ai-card>
<ai-card title="活动动态" v-show="currIndex === 2">
<template #content>
<Dynamic :instance="instance" :dict="dict" :id="params.id" v-show="currIndex === 2"></Dynamic>
</template>
</ai-card>
</template>
</ai-detail>
</template>
<script>
import Dynamic from './Dynamic'
export default {
name: 'Detail',
props: {
instance: Function,
dict: Object,
params: Object
},
components: {
Dynamic
},
data () {
return {
total: 0,
info: {},
id: '',
search: {
current: 1,
size: 10
},
currIndex: 0,
tableData: [],
colConfigs: [
{prop: 'name', label: '报名人员名称', align: 'center' },
{prop: 'createTime', label: '报名时间', align: 'center'},
{prop: 'phone', label: '联系方式', align: 'center' }
],
tabList: ['基本信息', '报名情况', '活动动态']
}
},
created () {
if (this.params && this.params.id) {
this.id = this.params.id
this.getInfo(this.params.id)
this.getList(this.params.id)
}
},
methods: {
getInfo (id) {
this.instance.post(`/app/appvillageactivityinfo/queryDetailById?id=${id}`).then(res => {
if (res.code === 0) {
this.info = res.data
this.info.url = res.data.url ? JSON.parse(res.data.url) : []
}
})
},
getList (id) {
this.instance.post(`/app/appvillageactivityuser/list`, null, {
params: {
...this.search,
activityId: 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>

View File

@@ -0,0 +1,238 @@
<template>
<div class="bbs">
<div v-if="list.length">
<div class="bbs-title">
<span></span>
<i>{{ list.length }}</i>
<span>条动态</span>
</div>
<div class="bbs-item" v-for="(item, index) in list" :key="index">
<div class="bbs-item__info">
<div class="bbs-item__info--top">
<div class="left">
<img :src="item.avatar" />
<h2>{{ item.name }}</h2>
</div>
<i>{{ item.createTime }}</i>
</div>
<div class="bbs-item__info--content">
<p>{{ item.content }}</p>
<ai-uploader v-if="item.images && item.images.length" :instance="instance" :value="item.images" :limit="9" disabled></ai-uploader>
<!-- <div class="text-button" @click="remove(item.id)">删除动态</div> -->
</div>
</div>
</div>
</div>
<ai-empty class="empty" v-else></ai-empty>
</div>
</template>
<script>
export default {
name: 'Add',
props: {
id: String,
instance: Function
},
data () {
return {
list: []
}
},
created () {
this.getInfo(this.id)
},
methods: {
getInfo (id) {
this.instance.post(`/app/appvillageactivitypost/list?size=1000&activityId=${id}`).then(res => {
if (res.code === 0) {
this.list = res.data.records.map(v => {
return {
...v,
images: v.images ? JSON.parse(v.images) : []
}
})
}
})
},
remove(id) {
this.$confirm('确定删除该数据?').then(() => {
this.instance.post(`/app/appvillageactivitypost/delete?id=${id}`).then((res) => {
if (res.code == 0) {
this.$message.success('删除成功!')
this.getList()
}
})
})
}
}
}
</script>
<style scoped lang="scss">
.bbs {
padding-top: 16px;
::v-deep .ai-detail__content {
background: #F3F6F9;
}
::v-deep .ai-empty__bg {
margin-top: 0;
}
.text-button {
cursor: pointer;
color: #5088FF;
font-size: 14px;
&:hover {
opacity: 0.8;
}
}
.bbs-replay {
margin-top: 16px;
padding: 0 16px;
background: #F5F6F7;
.bbs-replay__item {
padding: 16px 0;
border-bottom: 1px solid #DDDDDD;
.text-button {
margin-left: 48px;
}
& > p {
line-height: 19px;
margin: 8px 0 8px 48px;
font-size: 14px;
color: #333333;
}
.bbs-replay__item--top {
display: flex;
align-items: center;
img {
width: 40px;
height: 40px;
margin-right: 8px;
border-radius: 50%;
}
.right {
display: flex;
align-items: center;
justify-content: space-between;
flex: 1;
.right-user {
display: flex;
align-items: center;
}
h2 {
color: #333333;
font-size: 14px;
}
i {
padding: 0 4px;
font-style: normal;
font-size: 14px;
color: #999999;
}
span {
color: #999999;
font-size: 14px;
}
}
}
&:last-child {
border: none;
}
}
}
.bbs-item__info {
.bbs-item__info--content {
padding-left: 64px;
p {
font-size: 14px;
color: #333333;
margin-bottom: 10px;
line-height: 19px;
}
}
.bbs-item__info--top {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 6px;
padding-left: 16px;
.left {
display: flex;
align-items: center;
img {
width: 40px;
height: 40px;
margin-right: 8px;
border-radius: 50%;
}
h2 {
color: #333333;
font-size: 14px;
}
}
i {
color: #999999;
font-size: 14px;
font-style: normal;
}
}
}
.bbs-title {
display: flex;
align-items: center;
height: 56px;
line-height: 1;
margin: 0 0 16px;
padding: 0px 16px;
background: #FFFFFF;
color: #333333;
font-size: 16px;
border-radius: 4px;
border: 1px solid #D8E0E8;
i {
padding: 0 4px;
color: #5088FF;
font-style: normal;
}
}
.bbs-item {
margin-bottom: 16px;
padding: 16px;
background: #FFFFFF;
border-radius: 4px;
border: 1px solid #D8E0E8;
}
}
</style>

View File

@@ -0,0 +1,268 @@
<template>
<ai-list class="AppPetitionManage" isTabs>
<template slot="content">
<ai-search-bar class="search-bar">
<template slot="left">
<el-button type="primary" icon="iconfont iconAdd" @click="toAdd('')">发布活动</el-button>
<ai-select
v-model="search.status"
@change="search.current = 1, getList()"
placeholder="活动状态"
:selectList="dict.getDict('villageActivityStatus')">
</ai-select>
</template>
<template slot="right">
<el-input
v-model="search.title"
class="search-input"
size="small"
v-throttle="() => {search.current = 1, getList()}"
placeholder="请输入活动名称"
clearable
@change="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"
ref="aitableex"
:current.sync="search.current"
:size.sync="search.size"
v-loading="isLoading"
@getList="getList">
<el-table-column slot="options" width="180px" 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="toAdd(row.id)" :disabled="row.status === '1' || row.status === '2'">编辑</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,
areaId: String
},
data () {
return {
search: {
current: 1,
size: 10,
title: '',
status: ''
},
isLoading: false,
ids: [],
total: 10,
colConfigs: [
{ prop: 'title', label: '活动名称', align: 'left' },
{
prop: 'areaName', label: '活动地区', align: 'center' ,
render: (h, params) => {
return h('span', {
}, params.row.areaName)
}
},
{
prop: 'status', label: '活动状态', align: 'center',
render: (h, params) => {
return h('span', {
}, this.dict.getLabel('villageActivityStatus', params.row.status))
}
},
{ prop: 'realNum', label: '报名人数', align: 'center' },
{
prop: 'beginTime', width: '300px', label: '活动时间', align: 'center',
render: (h, params) => {
return h('span', {
}, params.row.beginTime + ' - ' + params.row.endTime)
}
},
{ slot: 'options', label: '操作', align: 'center' }
],
tableData: []
}
},
computed: {
...mapState(['user'])
},
created () {
this.isLoading = true
this.dict.load(['villageActivityStatus']).then(() => {
this.getList()
})
},
methods: {
getList() {
this.instance.post(`/app/appvillageactivityinfo/list`, null, {
params: {
...this.search,
areaId: this.areaId
}
}).then(res => {
if (res.code == 0) {
this.tableData = res.data.records
this.total = res.data.total
this.isLoading = false
} else {
this.isLoading = false
}
}).catch(() => {
this.isLoading = false
})
},
toAdd (id) {
this.$emit('change', {
type: 'Add',
params: {
id
}
})
},
remove (id) {
this.$confirm('确定删除该数据?').then(() => {
this.instance.post(`/app/appvillageactivityinfo/delete?ids=${id}`).then(res => {
if (res.code == 0) {
this.$message.success('删除成功!')
this.getList()
}
})
})
},
toDetail (id) {
this.$emit('change', {
type: 'Detail',
params: {
id: id
}
})
}
}
}
</script>
<style lang="scss" scoped>
.table-tags {
.el-tag {
margin-right: 8px;
margin-bottom: 8px;
border: 1px solid #D0D4DC;
background: #F3F4F7;
border-radius: 4px;
font-size: 13px;
color: #222222;
&:last-child {
margin-right: 0;
}
}
}
.ellipsis {
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
}
.tags {
.tag-item {
display: flex;
align-items: center;
padding-bottom: 30px;
padding-top: 30px;
border-bottom: 1px solid #EEEEEE;
&:first-child {
padding-top: 0;
}
.el-tag {
margin-right: 8px;
color: #222222;
}
h2 {
width: 88px;
margin-right: 40px;
text-align: right;
color: #888888;
font-size: 14px;
}
}
}
.avatar {
text-align: right;
img {
position: relative;
top: 4px;
width: 40px;
height: 40px;
border-radius: 2px;
border: 1px solid #CCCCCC;
}
}
.userinfo {
display: flex;
align-items: center;
line-height: 1;
.userinfo-right__top {
display: flex;
align-items: center;
margin-bottom: 10px;
cursor: pointer;
white-space: nowrap;
}
.userinfo-right__bottom {
text-align: left;
}
i {
cursor: pointer;
font-style: normal;
color: #888888;
font-size: 14px;
}
h3 {
margin-top: 0;
margin-bottom: 0;
margin-right: 8px;
color: #222222;
font-weight: normal;
font-size: 14px;
}
span {
color: #3C7FC8;
white-space: nowrap;
}
}
</style>

View File

@@ -0,0 +1,661 @@
<template>
<ai-list class="statistics" isTabs style="width: 100%" v-loading="loading">
<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="areaId"
:default-expanded-keys="defaultExpanded"
:default-checked-keys="defaultChecked"
@current-change="onTreeChange">
</el-tree>
</div>
</div>
</template>
<template slot="content">
<ai-card title="近12个月居民参与活动人数统计">
<template #content>
<div class="chart1" style="height: 300px; width: 100%;"></div>
<ai-empty v-if="false" style="height: 148px;"></ai-empty>
</template>
</ai-card>
<ai-card title="活动统计">
<template #right>
<el-date-picker
v-model="time1"
type="month"
size="small"
:clearable="false"
@change="getInfo"
value-format="yyyy-MM"
placeholder="请选择月份">
</el-date-picker>
</template>
<template #content>
<div class="middle">
<div class="left">
<div class="left-item">
<h2>活动发布数量</h2>
<div>
<span style="color: rgb(34, 102, 255);">{{ info['活动发布数量'] }}</span>
</div>
</div>
<div class="left-item">
<h2>活动报名人数</h2>
<div>
<span style="color: rgb(34, 170, 153);">{{ info['活动报名人数'] || 0 }}</span>
</div>
</div>
<div class="left-item">
<h2>发布动态条数</h2>
<div>
<span style="color: rgb(248, 180, 37);">{{ info['发布动态条数'] }}</span>
</div>
</div>
<div class="left-item">
<h2>发布动态人员占比</h2>
<div>
<span style="color: red;">{{ info['发布动态人员占比'] }}%</span>
</div>
</div>
</div>
<div class="right">
<h2>居民参与类型占比</h2>
<div class="right-chart">
<div class="chart2" style="height: 200px; width: 100%;"></div>
</div>
</div>
</div>
</template>
</ai-card>
<ai-card title="村民参与活动记录">
<template #right>
<el-date-picker
v-model="time2"
type="month"
size="small"
:clearable="false"
@change="getInfo"
value-format="yyyy-MM"
placeholder="请选择月份">
</el-date-picker>
</template>
<template #content>
<ai-table
style="margin-top: 12px;"
:border="true"
tableSize="small"
:total="total"
:tableData="list"
:col-configs="colConfigs"
:isShowPagination="false"
:stripe="false"
@getList="getInfo">
</ai-table>
</template>
</ai-card>
</template>
</ai-list>
</template>
<script>
import { mapState } from 'vuex'
import * as echarts from 'echarts'
export default {
name: 'Statistics',
props: {
instance: Function,
dict: Object
},
data () {
return {
chart1: null,
info: {},
chartWidth: '',
loading: false,
defaultExpanded: [],
defaultChecked: [],
areaTree: [],
defaultProps: {
children: 'children',
label: 'name'
},
total: 0,
colConfigs: [
{ prop: 'name', label: '姓名', align: 'left' },
{ prop: 'gender', label: '性别', align: 'center', formart: v => this.dict.getLabel('sex', v) },
{ prop: 'num1', label: '报名次数', align: 'center' },
{ prop: 'num2', label: '发布动态条数', align: 'center' }
],
time1: '',
time2: '',
chart2: '',
currIndex: -1,
list: [],
unitName: '',
areaId: ''
}
},
computed: {
...mapState(['user'])
},
watch: {
unitName (val) {
this.$refs.tree.filter(val)
}
},
mounted () {
this.time1 = this.$moment(new Date()).format('YYYY-MM')
this.time2 = this.$moment(new Date()).format('YYYY-MM')
this.areaId = this.user.info.areaId
this.areaName = this.user.info.areaName
this.getTree()
this.loading = true
this.$nextTick(() => {
this.chart1 = echarts.init(document.querySelector('.chart1'))
this.chart2 = echarts.init(document.querySelector('.chart2'))
window.addEventListener('resize', this.onResize)
this.dict.load('sex').then(() => {
this.getInfo()
})
})
},
destroyed () {
window.removeEventListener('resize', this.onResize)
},
methods: {
onResize () {
this.chart1.resize()
},
onTreeChange (e) {
this.areaId = e.id
this.areaName = e.name
this.$nextTick(() => {
this.getInfo()
})
},
filterNode(value, data) {
if (!value) return true
return data.name.indexOf(value) !== -1
},
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.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))
}
},
getInfo () {
this.loading = true
this.instance.post(`/app/appvillageactivityinfo/statistic?areaId=${this.areaId}&time1=${this.time1 || ''}&time2=${this.time2 || '-'}`).then(res => {
if (res.code == 0) {
this.info = res.data.total
this.initChart1(res.data.twelve)
this.initChart2(res.data.gender)
this.list = res.data.rank || []
this.loading = false
} else {
this.loading = false
}
})
},
initChart2 (data) {
const values = data && Object.keys(data).map(v => {
return {
value: data[v],
name: v
}
}) || []
let option = {
tooltip: {
trigger: 'item'
},
legend: {
right: '5%',
top: 'center',
orient: 'vertical'
},
series: [
{
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: '20',
color: '#2266FF'
}
},
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
},
normal:{
label:{
show: true,
formatter: '{b} : {c} ({d}%)'
},
labelLine :{show:true}
}
},
labelLine: {
show: false
},
color: ['#2266FF', '#22AA99', '#F8B425'],
data: values
}
]
}
this.chart2.setOption(option)
},
initChart1 (data) {
const x = data ? data.map(v => v.time) : []
let option = {
tooltip: {
trigger: 'axis'
},
legend: {
type: "plain"
},
grid: {
left: '10px',
right: '28px',
bottom: '14px',
top: '30px',
containLabel: true
},
color: ['#2266FF', '#22AA99', '#F8B425'],
xAxis: {
type: 'category',
axisLabel: {
align: 'center',
padding: [2, 0, 0, 0],
interval: 0,
fontSize: 14,
color: '#666666'
},
boundaryGap: false,
axisLine: {
lineStyle: {
color: '#E1E5EF'
}
},
data: x
},
yAxis: {
axisTick: {
length: 0,
show: false
},
splitLine: {
show: true,
lineStyle:{
color: ['#E1E5EF'],
width: 1,
type: 'solid'
}
},
nameTextStyle: {
color: '#666666',
align: 'left'
},
axisLine: {
show: false
},
axisLabel: {
color: '#666666'
},
type: 'value'
},
series: [
{
name: '活动报名人数',
type: 'line',
data: data.map(v => v.total)
},
{
name: '发布动态人数',
type: 'line',
data: data.map(v => v.active)
}
]
}
this.chart1.setOption(option)
}
}
}
</script>
<style scoped lang="scss">
.statistics {
padding: 0!important;
::v-deep .ai-list__content--right-wrapper {
background: transparent!important;
box-shadow: none!important;
padding: 0 0 0!important;
}
::v-deep .ai-list {
padding: 0!important;
}
.middle {
display: flex;
height: 220px;
& > div {
width: 50%;
}
.right {
h2 {
font-size: 16px;
}
}
.left {
display: flex;
flex-wrap: wrap;
flex: 1;
padding-right: 20px;
.left-item {
width: calc((100% - 10px) / 2);
padding: 16px;
margin-right: 10px;
margin-bottom: 10px;
background: #f9f9f9;
-webkit-box-shadow: 0 4px 6px -2px rgb(15 15 21 / 15%);
box-shadow: 0 4px 6px -2px rgb(15 15 21 / 15%);
border-radius: 4px;
&:nth-of-type(2n) {
margin-right: 0;
}
h2 {
margin-bottom: 16px;
color: #888;
font-size: 16px;
font-weight: normal;
}
div {
display: flex;
align-items: center;
i {
font-style: normal;
}
span {
font-size: 1.5em;
color: #333;
font-weight: 600;
}
}
}
}
}
.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;
::v-deep input {
width: 100%;
}
}
.el-button {
width: 84px;
flex-shrink: 1;
margin-right: 8px;
}
}
span {
color: #222222;
font-size: 14px;
}
::v-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;
}
}
}
}
::v-deep .ai-list__content--left {
margin-right: 10px;
}
.villagecode-left {
width: 100%;
height: auto;
background: #FAFAFB;
.villagecode-left__title {
display: flex;
align-items: center;
height: 40px;
padding: 0 16px;
background: #fff;
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;
}
}
}
}
::v-deep .ai-list__content--right {
.ai-list__content--right-wrapper {
min-height: 100%;
}
}
.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;
}
}
}
}
</style>

View File

@@ -0,0 +1,63 @@
<template>
<div class="AppVillageAlbum">
<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 Add from './components/Add'
export default {
name: 'AppVillageAlbum',
label: '乡村相册',
components: {
List,
Add
},
props: {
instance: Function,
dict: Object,
permissions: Function
},
data () {
return {
currIndex: '0',
component: 'List',
params: {},
areaId: '',
isShowDetail: false
}
},
methods: {
onChange (data) {
if (data.type === 'list') {
this.component = 'List'
this.params = data.params
}
if (data.type === 'detail') {
this.component = 'Detail'
this.params = data.params
}
if (data.type === 'add') {
this.component = 'Add'
this.params = data.params
}
}
}
}
</script>
<style lang="scss" scoped>
.AppVillageAlbum {
height: 100%;
}
</style>

View File

@@ -0,0 +1,123 @@
<template>
<ai-detail>
<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 label="相册主题" style="width: 100%;" prop="type"
:rules="[{required: true, message: '请选择相册主题', trigger: 'blur'}]">
<ai-select
v-model="form.type"
placeholder="请选择相册主题"
:selectList="dict.getDict('villagePictureAlbumType')">
</ai-select>
</el-form-item>
<el-form-item prop="areaId" style="width: 100%;" label="发布地区"
:rules="[{required: true, pattern: /([^0]\d{2}|0[^0]\d|0\d[^0])$/, message: '请选择到村', trigger: 'change'}]">
<ai-area-select @fullname="v => form.areaName = v" clearable always-show :instance="instance"
v-model="form.areaId" :disabled-level="disabledLevel"></ai-area-select>
</el-form-item>
<el-form-item label="图片" style="width: 100%;" prop="urlList" :rules="[{required: true, message: '请上传图片'}]">
<ai-uploader
:instance="instance"
v-model="form.urlList"
:limit="9">
</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>
import {mapState} from 'vuex'
export default {
name: 'Add',
props: {
instance: Function,
dict: Object,
params: Object
},
data() {
return {
info: {},
form: {
areaName: '',
areaId: '',
urlList: []
},
cropOps: {
width: "336px",
height: "210px"
},
id: ''
}
},
computed: {
...mapState(['user'])
},
created() {
this.form.areaId = this.user.info.areaId
this.disabledLevel = this.user.info.areaList.length
this.dict.load(['villagePictureAlbumType'])
if (this.params && this.params.id) {
this.id = this.params.id
this.getInfo(this.params.id)
}
},
methods: {
getInfo(id) {
this.instance.post(`/app/appcountrysidetourism/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/appvillagepicturealbum/addPictures`, {
...this.form,
id: this.params.id,
urlList: this.form.urlList.map(v => v.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>

View File

@@ -0,0 +1,538 @@
<template>
<ai-list class="list">
<template slot="title">
<ai-title title="乡村相册" isShowBottomBorder :instance="instance" :disabledLevel="disabledLevel" isShowArea v-model="search.areaId" @change="changeArea"></ai-title>
</template>
<template slot="content">
<ai-search-bar>
<template #left>
<ai-select
v-model="search.type"
@change="search.current = 1, getList()"
placeholder="请选择相册主题"
:selectList="dict.getDict('villagePictureAlbumType')">
</ai-select>
<el-date-picker
v-model="search.timeTag"
type="month"
size="small"
@change="search.current = 1, getList()"
value-format="yyyy-MM"
placeholder="请选择日期">
</el-date-picker>
</template>
</ai-search-bar>
<div v-loading="loading">
<div class="form-list__list">
<div class="list-item list-add" @click="toAdd('')">
<span class="iconfont iconAdd"></span>
<h2>添加相片</h2>
</div>
<div class="list-item" v-for="(item, index) in list" :key="index">
<div class="list-item__img">
<img :src="item.url" @click="prevImg(index)">
</div>
<div class="list-item__bottom">
<div class="left">
<span class="tag">{{ dict.getLabel('villagePictureAlbumType', item.type) }}</span>
<span>{{ item.createUserName }}</span>
</div>
<i>{{ item.createTime }}</i>
</div>
<div class="list-item__operate">
<el-button
type="text"
icon="iconfont iconExported"
class="list-item__operate--item"
@click="downloadImg(item.url, dict.getLabel('villagePictureAlbumType', item.type))">
下载
</el-button>
<el-button
@click="remove(item.id)"
type="text"
icon="iconfont iconDelete"
class="list-item__operate--item">
删除
</el-button>
</div>
</div>
</div>
</div>
<div class="images" v-viewer="{movable: true}" v-show="false">
<img v-for="(item, index) in imgList" :src="item" :key="index" alt="">
</div>
</template>
</ai-list>
</template>
<script>
import { mapState } from 'vuex'
import Viewer from 'v-viewer'
import Vue from 'vue'
Vue.use(Viewer)
export default {
name: 'FormList',
props: {
instance: Function,
dict: Object,
areaId: String
},
data () {
return {
search: {
current: 1,
areaId: '',
size: 1000000,
type: '',
timeTag: ''
},
isShowAdd: false,
form: {
},
list: [],
total: 0,
loading: false,
id: '',
disabledLevel: 0
}
},
computed: {
...mapState(['user']),
imgList () {
return this.list.map(v => v.url)
}
},
created () {
this.loading = true
this.disabledLevel = this.user.info.areaList.length - 1
this.search.areaId = this.user.info.areaId
this.dict.load(['villagePictureAlbumType']).then(() => {
this.getList()
})
},
methods: {
changeArea () {
this.loading = true
this.search.current = 1
this.$nextTick(() => {
this.getList()
})
},
prevImg (index) {
const viewer = this.$el.querySelector('.images').$viewer
viewer.view(index)
},
getList () {
this.instance.post(`/app/appvillagepicturealbum/list`, null, {
params: {
...this.search
}
}).then(res => {
if (res.code == 0) {
this.list = res.data.records
this.total = res.data.total
this.loading = false
} else {
this.loading = false
}
}).catch(() => {
this.loading = false
})
},
remove (id) {
this.$confirm('确定删除该相片?').then(() => {
this.instance.post(`/app/appvillagepicturealbum/delete?ids=${id}`).then(res => {
if (res.code == 0) {
this.$message.success('删除成功!')
this.getList()
}
})
})
},
downloadImg (url, name) {
let image = new Image()
image.setAttribute('crossOrigin', 'anonymous')
image.onload = function() {
let canvas = document.createElement('canvas')
canvas.width = image.width
canvas.height = image.height
let context = canvas.getContext('2d')
context.drawImage(image, 0, 0, image.width, image.height)
let url = canvas.toDataURL("image/png")
let a = document.createElement("a")
let event = new MouseEvent("click")
a.download = name
a.href = url
a.dispatchEvent(event)
}
image.src = url
},
toStop (id) {
this.$confirm('确定停止该表单?').then(() => {
this.instance.post(`/app/appquestionnairetemplate/stopRelease?id=${id}`).then(res => {
if (res.code === 0) {
this.$message.success('停止成功!')
this.getList()
}
})
})
},
showShare (info, isPreview) {
this.loading = true
this.info = info
this.instance.post(`/app/appquestionnairetemplate/queryQrCode?id=${info.id}`).then(res => {
if (res.code == 0) {
this.info.linkUrl = res.data.linkUrl
this.info.qrCodeUrl = res.data.qrCodeUrl
this.$nextTick(() => {
if (isPreview) {
this.isShowPreview = true
this.info.linkUrl = `${res.data.linkUrl}&preview=true#form`
} else {
this.isShowSuccess = true
}
})
}
this.loading = false
}).catch(() => {
this.loading = false
})
},
toAdd (id) {
this.$emit('change', {
type: 'add',
params: {
id
}
})
}
}
}
</script>
<style scoped lang="scss">
.list {
::v-deep .ai-list__content {
width: 100%;
.ai-list__content--right {
width: 100%!important;
.ai-list__content--right-wrapper {
padding: 0!important;
background: transparent!important;
box-shadow: none!important;
}
}
}
::v-deep.el-pager {
li.active + li {
border-left: 1px solid #D0D4DC;
}
}
.newPagination {
width: 100%;
display: flex;
align-items: center;
height: 64px;
padding: 0 40px!important;
.el-pagination {
width: 100%;
padding: 0;
}
::v-deep .el-pager li.active {
background-color: #fff !important;
color: #2266FF !important;
border-color: #2266FF;
}
::v-deep .el-pager li {
background-color: #fff;
border: solid 1px #d0d4dc;
margin-left: 8px;
border-radius: 4px !important;
line-height: 26px !important;
}
.paginationPre {
display: flex;
height: 28px;
line-height: 1;
font-size: 14px;
font-weight: normal;
align-items: center;
.pagination-btns {
display: flex;
align-items: center;
gap: 8px;
color: #2266FF !important;
::v-deep span, ::v-deep div {
font-size: 12px;
cursor: pointer;
color: #2266FF !important;
&:hover {
opacity: 0.8;
}
}
}
.paginationPre-total {
font-size: 12px;
color: #555;
label {
padding: 0 2px;
font-weight: 700;
}
}
& > * + * {
margin-left: 24px;
}
::v-deep .el-pagination button, .el-pagination span:not([class*=suffix]) {
line-height: 1 !important;
}
::v-deep.el-checkbox {
padding-left: 14px;
display: flex;
align-items: center;
.el-checkbox__input, .el-checkbox__inner {
width: 14px;
height: 14px;
min-width: 0 !important;
line-height: 1 !important;
}
.el-checkbox__label {
font-size: 12px;
color: #222222;
height: auto !important;
line-height: 1 !important;
padding-left: 3px !important;
}
}
}
}
.form-list__list {
display: flex;
flex-wrap: wrap;
margin-top: 8px;
.list-item {
display: flex;
position: relative;
flex-direction: column;
justify-content: space-between;
margin-bottom: 12px;
padding: 18px 16px 16px;
.list-item__img {
width: 100%;
height: 140px;
cursor: pointer;
img {
width: 100%;
height: 140px;
object-fit: none;
}
}
&:hover {
.list-item__operate {
display: flex;
}
}
.list-item__operate {
display: none;
align-items: center;
position: absolute;
left: 0;
bottom: 0;
z-index: 1;
width: 100%;
height: 52px;
text-align: center;
background: #F7F8FA;
& > div {
flex: 1;
}
::v-deep .el-button {
margin-left: 0;
padding: 0;
i {
color: #8899BB;
font-size: 14px;
transition: all 0.3s;
}
.el-button + .el-button {
margin-left: 0;
}
span {
margin-left: 0;
color: #555555;
font-size: 12px;
transition: all 0.3s;
}
&:hover {
&.is-disabled {
i {
color: #8899BB;
}
span {
color: #555555;
}
}
}
}
.list-item__operate--item {
flex: 1;
&:hover {
::v-deep i, ::v-deep span {
color: #2266FF;
}
}
}
}
.list-item__bottom {
display: flex;
align-items: center;
justify-content: space-between;
color: #888888;
font-size: 12px;
i {
font-style: normal;
}
.left {
display: flex;
align-items: center;
.tag {
height: 26px;
line-height: 26px;
margin-right: 8px;
padding: 0 6px;
border-radius: 4px;
background: #42D784;
color: #fff;
}
}
}
p {
line-height: 22px;
color: #333333;
font-size: 14px;
font-weight: 700;
}
.list-item__user {
display: flex;
align-items: center;
margin-top: 12px;
color: #888888;
font-size: 12px;
line-height: 20px;
& > div:first-child {
margin-right: 8px;
}
}
.list-item__title {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 14px;
h2 {
color: #2EA222;
font-size: 12px;
}
span {
width: 64px;
height: 24px;
line-height: 24px;
text-align: center;
border-radius: 4px;
font-size: 12px;
}
}
}
.list-add {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
padding: 0;
cursor: pointer;
span {
font-size: 32px;
color: #8899bb;
}
h2 {
color: #555555;
font-size: 12px;
}
&:hover {
opacity: 0.6;
}
}
& > div {
width: calc((100% - 60px) / 4);
height: 216px;
margin: 0 20px 20px 0;
background: #FFFFFF;
box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.05);
border-radius: 2px;
&:nth-of-type(4n) {
margin-right: 0;
}
}
}
}
</style>

View File

@@ -0,0 +1,73 @@
<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'
import Detail from './components/Detail'
export default {
name: 'AppVillagerDiscussion',
label: '居民议事',
props: {
instance: Function,
dict: Object
},
data () {
return {
component: 'List',
params: {},
include: []
}
},
components: {
Add,
List,
Detail
},
mounted () {
},
methods: {
onChange (data) {
if (data.type === 'Add') {
this.component = 'Add'
this.params = data.params
}
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">
.doc-circulation {
height: 100%;
background: #F3F6F9;
overflow: auto;
}
</style>

View File

@@ -0,0 +1,248 @@
<template>
<ai-detail>
<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 label="主题" style="width: 100%;" prop="content" :rules="[{required: true, message: '请输入主题', trigger: 'blur'}]">
<el-input type="textarea" :rows="5" v-model="form.content" clearable placeholder="请输入主题..." :maxlength="500" show-word-limit></el-input>
</el-form-item>
<el-form-item prop="areaId" style="width: 100%;" label="发布地区" :rules="[{required: true, message: '请选择到村', trigger: 'change'}]">
<ai-area-select @fullname="v => form.areaName = v" clearable always-show :instance="instance" v-model="form.areaId" :disabled-level="disabledLevel"></ai-area-select>
</el-form-item>
<el-form-item label="议事截止时间" prop="discussDeadline" :rules="[{required: true, message: '请选择议事截止时间', trigger: 'change'}]">
<el-date-picker
v-model="form.discussDeadline"
type="datetime"
style="width: 100%;"
size="small"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="选择议事截止时间">
</el-date-picker>
</el-form-item>
<el-form-item label="公示截止时间" prop="publicityDeadline">
<el-date-picker
v-model="form.publicityDeadline"
size="small"
style="width: 100%;"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="选择公示截止时间">
</el-date-picker>
</el-form-item>
<el-form-item label="议事类型" prop="type" :rules="[{required: true, message: '请选择议事类型', trigger: 'change'}]">
<el-radio-group v-model="form.type">
<el-radio :label="item.dictValue" v-for="(item, index) in dict.getDict('discussType')" :key="index">{{ item.dictName }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="form.type === '1'" class="vite-form__item" style="width: 100%;" label="投票选项" prop="voteItems" :rules="[{required: true, message: '请添加投票选项', trigger: 'change'}]">
<draggable
v-model="form.voteItems"
:animation="340"
group="select">
<el-form-item class="move-item" style="width: 100%" label-width="80px" :label="'选项' + (index + 1)" v-for="(item, index) in form.voteItems" :key="'选项' + (index + 1)">
<div class="form-flex">
<el-input show-word-limit style="width:400px" v-model="item.content" :maxlength="200" size="small" placeholder="请输入选项"></el-input>
<el-button type="danger" size="small" @click="removeVote(index)">删除</el-button>
</div>
</el-form-item>
</draggable>
<el-button type="primary" size="small" @click="addVote">添加选项</el-button>
</el-form-item>
<el-form-item v-if="form.type === '1'" label="是否匿名投票" prop="anonymous" :rules="[{required: true, message: '请选择是否匿名投票', trigger: 'change'}]">
<el-switch
v-model="form.anonymous"
active-value="1"
inactive-value="0">
</el-switch>
</el-form-item>
<el-form-item v-if="form.type === '1'" label="投票方式" prop="voteType" :rules="[{required: true, message: '请选择投票方式', trigger: 'change'}]">
<el-radio-group v-model="form.voteType">
<el-radio label="0">单选</el-radio>
<el-radio label="1">多选</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="图片" style="width: 100%;" prop="images">
<ai-uploader
:instance="instance"
isShowTip
v-model="form.images"
:limit="9">
</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" :loading="isLoading">提交</el-button>
</template>
</ai-detail>
</template>
<script>
import draggable from 'vuedraggable'
import { mapState } from 'vuex'
export default {
name: 'Add',
props: {
instance: Function,
dict: Object,
params: Object
},
components: {
draggable
},
data () {
return {
info: {},
form: {
content: '',
areaId: '',
areaName: '',
anonymous: '0',
discussDeadline: '',
publicityDeadline: '',
type: '0',
voteType: '0',
voteItems: [],
anonymity: '1',
images: []
},
isLoading: false,
keys: ['A', 'B', 'C', 'D', 'E', 'F', 'G'],
id: ''
}
},
computed: {
...mapState(['user'])
},
created () {
this.form.areaId = this.user.info.areaId
this.form.areaName = this.user.info.areaName
this.disabledLevel = this.user.info.areaList.length
if (this.params && this.params.id) {
this.id = this.params.id
this.getInfo(this.params.id)
}
},
methods: {
getInfo (id) {
this.instance.post(`/app/appvillagediscuss/queryDetailById?id=${id}`).then(res => {
if (res.code === 0) {
this.form = res.data
this.form.content = res.data.title
this.form.images = res.data.images ? JSON.parse(res.data.images) : []
}
})
},
addVote () {
if (this.form.voteItems > 7) {
return this.$message.error('选项不能大于7个')
}
this.form.voteItems.push({
content: ''
})
},
removeVote (index) {
this.form.voteItems.splice(index, 1)
},
confirm () {
this.$refs.form.validate((valid) => {
if (valid) {
const endTime = new Date(this.form.discussDeadline).getTime()
const endPublicityTime = this.form.publicityDeadline ? new Date(this.form.publicityDeadline).getTime() : 0
const nowTime = new Date().getTime()
if (endTime - nowTime < 0) {
return this.$message.error('议事截止时间不能早于当前时间')
}
if (endPublicityTime && endPublicityTime - endTime < 0) {
return this.$message.error('公示截止时间不能早于议事截止时间')
}
if (this.form.type === '1' && this.form.voteItems.length < 2) {
return this.$message.error('投票选项不能少于2')
}
if (this.form.type === '1') {
this.form.voteItems = this.form.voteItems.map((v, index) => {
return {
content: v.content,
item: this.keys[index]
}
})
for (let v of this.form.voteItems) {
if (!v.content) {
return this.$message.error(`请输入选项${v.item}的内容`)
}
}
}
this.isLoading = true
this.instance.post(`/app/appvillagediscuss/addOrUpdate`, {
...this.form,
createUserId: this.user.info.id,
createUserName: this.user.info.name,
images: this.form.images.length ? JSON.stringify(this.form.images) : '',
}).then(res => {
if (res.code == 0) {
this.$message.success('提交成功')
setTimeout(() => {
this.isLoading = false
this.cancel(true)
}, 300)
}
}).catch(() => {
this.isLoading = false
})
}
})
},
cancel (isRefresh) {
this.$emit('change', {
type: 'list',
isRefresh: !!isRefresh
})
}
}
}
</script>
<style scoped lang="scss">
.move-item {
::v-deep .el-form-item__label {
cursor: move;
}
}
.vite-form__item {
.form-flex {
display: flex;
align-items: center;
.el-button {
margin-left: 20px;
}
::v-deep .el-form-item__content {
margin-left: 0!important;
}
}
}
</style>

View File

@@ -0,0 +1,278 @@
<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" @change="onChange"></AiSidebar>
<ai-card title="议题信息" v-show="currIndex === 0">
<template #content>
<ai-wrapper>
<ai-info-item label="主题" :value="info.content" isLine></ai-info-item>
<ai-info-item label="发布地区" :value="info.areaName" isLine></ai-info-item>
<ai-info-item label="议事截止时间" :value="info.discussDeadline"></ai-info-item>
<ai-info-item label="公示截止时间" :value="info.publicityDeadline"></ai-info-item>
<ai-info-item label="议事类型" :value="dict.getLabel('discussType', info.type)" isLine></ai-info-item>
<ai-info-item label="是否匿名投票" v-if="info.type === '1'" :value="info.anonymous === '1' ? '是' : '否'"></ai-info-item>
<ai-info-item label="投票方式" v-if="info.type === '1'" :value="info.voteType === '0' ? '单选' : '多选'"></ai-info-item>
<ai-info-item label="图片" isLine>
<ai-uploader
:instance="instance"
disabled
v-model="info.images"
:limit="9">
</ai-uploader>
</ai-info-item>
</ai-wrapper>
</template>
</ai-card>
<ai-card title="意见征集" v-if="info.type === '0'" v-show="currIndex === 1">
<template #right>
<el-button type="primary" size="small" v-if="user.info.id === info.createUserId && info.status === '0'" @click="isShowAdd = true">发表意见</el-button>
</template>
<template #content>
<ai-table
class="detail-table__table"
:border="true"
:tableData="tableData"
:col-configs="colConfigs"
:total="total"
:current.sync="search.current"
:size.sync="search.size"
:stripe="false"
@getList="getList">
</ai-table>
</template>
</ai-card>
<ai-card title="投票统计" v-show="currIndex === 1 && info.type === '1'">
<template #content>
<h2 class="detail-title">选项</h2>
<ai-wrapper>
<ai-info-item :label="item.item + ''" :value="item.content" isLine v-for="(item, index) in info.voteItems" :key="index"></ai-info-item>
</ai-wrapper>
<div class="chart" style="width: 800px; height: 240px; margin: 0 auto;"></div>
<ai-table
class="detail-table__table"
:border="true"
:tableData="tableData"
:col-configs="voteColConfigs"
:total="total"
:current.sync="search.current"
:size.sync="search.size"
:stripe="false"
@getList="getList">
</ai-table>
</template>
</ai-card>
<ai-dialog
:visible.sync="isShowAdd"
width="680px"
height="580px"
title="发表意见"
@close="onClose"
@onConfirm="onConfirm">
<el-form ref="form" class="ai-form" :model="form" label-width="110px" label-position="right">
<el-form-item label="发表意见" prop="content" style="width: 100%;" :rules="[{ required: true, message: '请发表你的观点和意见', trigger: 'blur' }]">
<el-input size="small" type="textarea" :rows="5" show-word-limit :maxlength="140" placeholder="请发表你的观点和意见" v-model="form.content"></el-input>
</el-form-item>
</el-form>
</ai-dialog>
</template>
</ai-detail>
</template>
<script>
import * as echarts from 'echarts'
import { mapState } from 'vuex'
export default {
name: 'Detail',
props: {
instance: Function,
dict: Object,
params: Object
},
data () {
return {
info: {},
id: '',
search: {
current: 1,
size: 10
},
isShowAdd: false,
form: {
content: ''
},
total: 0,
currIndex: 0,
tableData: [],
colConfigs: [
{prop: 'content', label: '发言内容', align: 'center'},
{prop: 'suport', label: '获赞次数', align: 'center'},
{prop: 'createTime', label: '发言时间', align: 'center'},
{prop: 'createUserId', label: '发言身份', align: 'center', formart: v => v === this.info.createUserId ? '话事人' : '居民'}
],
type: '',
statistic: {},
tabList: ['议题信息', '意见征集']
}
},
computed: {
...mapState(['user']),
voteColConfigs () {
return [
{prop: 'createTime', label: '投票时间', align: 'center'},
{
prop: 'userName',
label: '发言人',
align: 'center',
render: (h, { row }) => {
return h('span', {}, this.info.anonymous === '1' ? '居民' : `${row.userName}${row.phone ? '-' + row.phone : ''}`)
}
},
{prop: 'item', label: '投票选项', align: 'center'}
]
}
},
created () {
this.getInfo(this.params.id)
},
methods: {
onChange (e) {
if (e === 1 && this.info.type === '1') {
this.$nextTick(() => {
this.initChart(this.statistic)
})
}
},
getInfo (id) {
this.instance.post(`/app/appvillagediscuss/queryDetailById?id=${id}`).then(res => {
if (res.code === 0) {
this.info = res.data
this.info.images = res.data.images ? JSON.parse(res.data.images) : []
this.type = res.data.type
this.getList()
if (res.data.type === '1') {
this.statistic = res.data.statistic
this.tabList = ['议题信息', '投票表决']
}
}
})
},
getList() {
this.instance.post(`${this.type === '0' ? '/app/appvillagediscussmessage/list' : '/app/appvillagediscussvote/list'}`, null, {
params: {
discussId: this.params.id,
...this.search
}
}).then(res => {
if (res.code == 0) {
this.tableData = res.data.records
this.total = res.data.total
}
})
},
initChart(data) {
this.chart = echarts.init(document.querySelector('.chart'))
const option = {
tooltip: {},
color: ['#2896FF', '#09DBFE', '#61FDB9', '#FFBB69', '#8429FF', '#ea7ccc'],
legend: {
right: '5%',
top: 'center',
orient: 'vertical',
formatter: function(name) {
let data = option.series[0].data
let total = 0
let tarValue = 0
for (let i = 0, l = data.length; i < l; i++) {
total += data[i].value
if (data[i].name == name) {
tarValue = data[i].value
}
}
let p = total === 0 ? 0 : (tarValue / total * 100).toFixed(0)
return name + '' + tarValue + '票' + ' ' + p + '%'
}
},
series: [
{
type: 'pie',
radius: '50%',
data: Object.keys(data).map(v => {
return {
value: data[v],
name: v
}
}),
label : {
normal : {
formatter: '{b}({d}%)',
textStyle : {
fontWeight : 'normal',
fontSize : 15
}
}
}
}
]
}
this.chart.setOption(option)
},
onConfirm () {
this.$refs.form.validate((valid) => {
if (valid) {
this.instance.post(`/app/appvillagediscussmessage/addOrUpdate`, {
...this.form,
discussId: this.params.id,
createUserId: this.user.info.name,
createUserName: this.user.info.id,
avatar: this.user.info.avatar
}).then(res => {
if (res.code === 0) {
this.$message.success('添加成功')
this.isShowAdd = false
this.search.current = 1
this.getList()
}
})
}
})
},
onClose () {
this.form.content = ''
},
cancel (isRefresh) {
this.$emit('change', {
type: 'list',
isRefresh: !!isRefresh
})
}
}
}
</script>
<style scoped lang="scss">
.detail-title {
font-weight: normal;
font-size: 16px;
font-weight: 600;
}
</style>

View File

@@ -0,0 +1,174 @@
<template>
<ai-list class="notice">
<template slot="title">
<ai-title title="居民议事" isShowBottomBorder isShowArea v-model="search.areaId" :instance="instance" @change="search.current = 1, getList()"></ai-title>
</template>
<template slot="content">
<ai-search-bar class="search-bar">
<template #left>
<ai-select placeholder="请选择议事类型" v-model="search.type" clearable @change="search.current = 1, getList()" :selectList="dict.getDict('discussType')"></ai-select>
<ai-select placeholder="请选择发布状态" v-model="search.status" clearable @change="search.current = 1, getList()" :selectList="dict.getDict('discussStatus')"></ai-select>
<el-button size="small" type="primary" icon="iconfont iconAdd" @click="toAdd('')">发起议事</el-button>
</template>
<template #right>
<el-input
v-model="search.title"
class="search-input"
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;"
: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="160px" fixed="right" label="操作" align="center">
<template slot-scope="{ row }">
<div class="table-options">
<el-button type="text" title="详情" @click="toDetail(row.id)">详情</el-button>
<el-button type="text" title="取消公示" @click="changeStatus(row)" :disabled="row.status !== '1'">结束公示</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: '',
type: '',
title: '',
areaId: ''
},
currIndex: -1,
areaList: [],
total: 10,
colConfigs: [
{ prop: 'content', label: '议事主题', align: 'left', width: '200px' },
{ prop: 'type', label: '议事类型', align: 'center', formart: v => this.dict.getLabel('discussType', v) },
{ prop: 'createUserName', label: '话事人', align: 'center' },
{ prop: 'msgCountTotal', label: '观点数量', align: 'center', formart: v => v === 0 ? '-' : v },
{ prop: 'voteCount', label: '投票数量', align: 'center', formart: v => v === 0 ? '-' : v },
{ prop: 'status', label: '发布状态', align: 'center', formart: v => this.dict.getLabel('discussStatus', v) },
{ prop: 'createTime', label: '发布时间', align: 'center' },
{ slot: 'options', label: '操作', align: 'center' }
],
areaName: '',
unitName: '',
tableData: []
}
},
computed: {
...mapState(['user'])
},
created () {
this.search.areaId = this.user.info.areaId
this.dict.load(['discussType', 'discussStatus']).then(() => {
this.getList()
})
},
methods: {
getList() {
this.instance.post(`/app/appvillagediscuss/listUp`, null, {
params: {
type: 0,
...this.search
}
}).then(res => {
if (res.code == 0) {
this.tableData = res.data.records.map(v => {
return {
...v,
content: v.content || v.title
}
})
this.total = res.data.total
}
})
},
changeStatus (item) {
this.$confirm('是否要结束公示', {type: 'warning'}).then(() => {
this.instance.post('/app/appvillagediscuss/finishPublic', {
status: '2',
id: item.id
}).then(res => {
if (res && res.code == 0) {
this.$message.success('结束公示成功')
this.getList()
}
})
})
},
remove(id) {
this.$confirm('确定删除该数据?').then(() => {
this.instance.post(`/app/appvillagediscuss/delete?ids=${id}`).then(res => {
if (res.code == 0) {
this.$message.success('删除成功!')
this.getList()
}
})
})
},
toDetail (id) {
this.$emit('change', {
type: 'Detail',
params: {
id: id || ''
}
})
},
toAdd(id) {
this.$emit('change', {
type: 'Add',
params: {
id: id || ''
}
})
}
}
}
</script>
<style lang="scss" scoped>
.notice {
}
</style>

View File

@@ -0,0 +1,40 @@
<template>
<div class="AppWeddingsFunerals">
<List
slot="content"
:instance="instance"
:dict="dict"
:permissions="permissions">
</List>
</div>
</template>
<script>
import List from './components/List.vue'
export default {
name: 'AppWeddingsFunerals',
label: '婚丧嫁娶',
components: {
List
},
props: {
instance: Function,
dict: Object,
permissions: Function
},
data () {
return {
}
}
}
</script>
<style lang="scss" scoped>
.AppWeddingsFunerals {
height: 100%;
}
</style>

View File

@@ -0,0 +1,210 @@
<template>
<ai-list class="list">
<ai-title slot="title" title="婚丧嫁娶" isShowBottomBorder></ai-title>
<template slot="content">
<div class="statistics-top">
<div class="statistics-top__item">
<span>活动登记数量</span>
<h2 style="color: #2266FF;">{{ info['丧礼登记数量'] }}</h2>
</div>
<div class="statistics-top__item">
<span>干部参与和操办登记数量</span>
<h2 style="color: #22AA99;">{{ info['干部参与和操办登记数量'] }}</h2>
</div>
<div class="statistics-top__item">
<span>婚礼登记数量</span>
<h2 style="color: #F8B425">{{ info['婚礼登记数量'] }}</h2>
</div>
<div class="statistics-top__item">
<span>丧礼登记数量</span>
<h2 style="color: red">{{ info['丧礼登记数量'] }}</h2>
</div>
</div>
<div class="content">
<ai-search-bar bottomBorder>
<template #left>
<el-button icon="iconfont iconDelete" size="small" @click="removeAll" :disabled="ids.length == 0">删除 </el-button>
</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"
@selection-change="v => (ids = v.map((e) => e.id))"
@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>
</div>
</template>
</ai-list>
</template>
<script>
export default {
name: 'List',
props: {
instance: Function,
dict: Object
},
data () {
return {
search: {
current: 1,
size: 10,
name: ''
},
info: {},
colConfigs: [
{ type: 'selection' },
{ prop: 'name', label: '事主姓名' },
{ prop: 'phone', align: 'center', label: '联系电话' },
{ prop: 'type', align: 'center', label: '类型', formart: v => this.dict.getLabel('marriageType', v) },
{ prop: 'modeType', align: 'center', label: '方式', formart: v => this.dict.getLabel('modeType', v) },
{ prop: 'personType', align: 'center', label: '人员性质', formart: v => this.dict.getLabel('marriagePersonType', v) },
{ prop: 'createTime', align: 'center', label: '发布时间' }
],
ids: [],
tableData: [],
total: 0,
loading: false
}
},
created () {
this.dict.load(['marriageType', 'marriagePersonType', 'modeType']).then(() => {
this.getList()
})
},
mounted () {
this.loading = true
},
methods: {
getList () {
this.instance.post(`/app/appmarriagefuneralinfo/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()
},
getTotalInfo () {
this.instance.post(`/app/appmarriagefuneralinfo/queryDataStatistics`).then(res => {
if (res.code == 0) {
let info = {}
res.data.forEach(v => {
info[v.name] = v.v1
})
this.info = info
}
})
},
remove (id) {
this.$confirm('确定删除该数据?').then(() => {
this.instance.post(`/app/appmarriagefuneralinfo/delete?ids=${id}`).then(res => {
if (res.code == 0) {
this.$message.success('删除成功!')
this.getList()
}
})
})
},
removeAll() {
var id = this.ids.join(',')
this.remove(id)
}
}
}
</script>
<style scoped lang="scss">
.list {
::v-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>

View File

@@ -0,0 +1,56 @@
<template>
<keep-alive include="gmScore">
<component :is="currentPage" v-bind="$props" @change="onChange"/>
</keep-alive>
</template>
<script>
import gridScoreManage from "./components/gridScoreManage.vue"
import gridScoreRules from "./components/gridScoreRules.vue"
import gridScoreStatistics from './components/gridScoreStatistics.vue'
import gridScoreDetail from './components/gridScoreDetail.vue'
import gmScore from './components/gmScore.vue'
export default {
name: 'AppGridMemberScore',
label: "网格员积分",
props: {
instance: Function,
dict: Object,
permissions: Function,
},
computed: {
currentPage() {
let {hash} = this.$route
return hash == "#gridScoreDetail" ? gridScoreDetail :
hash == "#gridScoreRules" ? gridScoreRules :
hash == "#gridScoreStatistics" ? gridScoreStatistics :
hash == "#gridScoreManage" ? gridScoreManage : gmScore
}
},
components: {
gmScore,
gridScoreManage,
gridScoreRules,
gridScoreStatistics,
gridScoreDetail,
},
methods: {
onChange(data) {
let {type, params: query} = data,
hash = ["gridScoreManage", "gridScoreRules","gridScoreStatistics"].includes(type) ? "" : "#" + type
this.$router.push({hash, query})
}
}
}
</script>
<style lang="scss" scoped>
.AppGridMemberScore {
height: 100%;
width: 100%;
}
</style>

View File

@@ -0,0 +1,89 @@
<template>
<ai-list class="AppGridMemberScore">
<template slot="title">
<ai-title title="网格员积分" :isShowBottomBorder="false" :instance="instance" >
<template slot="sub">
<div>网格员可通过完成某些任务获取一定数量的积分积分可去兑换相应的奖励</div>
</template>
</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 :is="tab.comp" v-if="currIndex === String(i)" :ref="tab.name" v-on="$listeners"
:areaId="areaId" :instance="instance" :dict="dict" :permissions="permissions"/>
</el-tab-pane>
</el-tabs>
</template>
</ai-list>
</template>
<script>
import girdScoreManage from "./gridScoreManage.vue"
import gridScoreRules from "./gridScoreRules.vue"
import gridScoreStatistics from './gridScoreStatistics.vue'
import {mapState} from 'vuex'
export default {
name: 'AppGridMemberScore',
label: "网格员积分",
components: {
girdScoreManage,
gridScoreRules,
gridScoreStatistics
},
props: {
instance: Function,
dict: Object,
permissions: Function,
},
data() {
return {
currIndex: "0",
areaId: '',
}
},
computed: {
...mapState(['user']),
tabs() {
return [
{
label: "积分管理",
name: "girdScoreManage",
comp: girdScoreManage,
permission: "",
},
{
label: "积分规则",
name: "gridScoreRules",
comp: gridScoreRules,
permission: "",
},
{
label: "积分统计",
name: "gridScoreStatistics",
comp: gridScoreStatistics,
permission: "",
},
]
}
},
created() {
this.areaId = this.user.info.areaId
// this.$dict.load("")
},
methods: {
},
}
</script>
<style lang="scss" scoped>
.AppGridMemberScore {
height: 100%;
width: 100%;
}
</style>

View File

@@ -0,0 +1,341 @@
<template>
<section class="gridScoreDetail">
<ai-title slot="title" title="网格员积分详情" isShowBottomBorder :isShowBack="true" @onBackClick="cancel(false)"/>
<el-row style="margin-top: 20px;">
<div class="card_list">
<div class="card">
<h2>姓名</h2>
<p class="color1">{{ data.userName }}</p>
</div>
<div class="card">
<h2>积分余额</h2>
<p class="color2">{{ data.integral || 0 }}</p>
</div>
<div class="card">
<h2>已用积分</h2>
<p class="color3">{{ data.usedIntegral || 0 }}</p>
</div>
</div>
</el-row>
<el-row class="echertsBox" style="margin-bottom: 16px">
<div class="title">
<h4>事件汇总</h4>
<div class="timecSelect">
时间<el-date-picker size="small" value-format="yyyy-MM-dd" @change="timeChange" v-model="timeList" type="daterange" range-separator="至" :start-placeholder="startPla" :end-placeholder="endPla"></el-date-picker>
</div>
</div>
<div class="bar_Box">
<div id="chartDom" style="height: 230px; width: 100%;" v-show="xData.length && yData.length"></div>
<ai-empty style="height: 200px; width: 100%;" v-show="!xData.length && !yData.length"></ai-empty>
</div>
</el-row>
<ai-card>
<ai-title slot="title" title="余额变动明细"/>
<template #content>
<ai-search-bar>
<template #left>
<ai-select v-model="search.type" placeholder="请选择类型" @change="search.current=1,getIntegralChange()"
:selectList="dict.getDict('integralType')"/>
</template>
<template #right>
<ai-download :instance="instance" :url="`/app/appintegraluser/changeIntegralExport?id=${$route.query.id}`" :params="search" fileName="网格员余额变动明细"
:disabled="tableData.length == 0">
<el-button size="small">导出</el-button>
</ai-download>
</template>
</ai-search-bar>
<ai-table :tableData="tableData" :total="total" :current.sync="search.current" :size.sync="search.size"
@getList="getIntegralChange" :col-configs="colConfigs" :dict="dict">
<el-table-column slot="changeIntegral" label="变动积分" align="center">
<template slot-scope="{ row }">
<span v-if="row.integralType == 3">{{ row.changeIntegral | formatTime }}</span>
<span v-if="row.integralType == 0">{{ row.integralCalcType == 0 ? '-' : '+' }}{{ row.changeIntegral }}</span>
</template>
</el-table-column>
<el-table-column slot="integralType" label="类型" align="center">
<template slot-scope="{ row }">
<span v-if="row.integralType == 0">积分调整</span>
<span v-else>{{ row.eventType }}</span>
</template>
</el-table-column>
<el-table-column slot="eventDesc" label='事件' align="center" width="400px" show-overflow-tooltip>
<template slot-scope="{ row }">
<span v-if="row.integralType == 0">{{ row.eventDesc }}</span>
<span v-else>{{ row.eventName }}</span>
</template>
</el-table-column>
</ai-table>
</template>
</ai-card>
</section>
</template>
<script>
import dayjs from "dayjs";
import * as echarts from 'echarts';
export default {
name: "gridScoreDetail",
data() {
return {
myChart: null,
tableData: [],
search: {
name: '',
girdId: '',
type: '',
current: 1,
size: 10,
},
total: 0,
girdList: [],
timeList: [],
data: {},
startTime: '',
endTime: '',
xData: [],
yData: [],
startPla: '',
endPla: ''
}
},
props: {
instance: Function,
dict: Object,
permissions: Function,
},
computed: {
colConfigs() {
return [
{ prop: "doTime", label: '时间', align: "left", width: "200px" },
{ slot: "integralType", label: '类型', align: "center", width: "240px", dict:"integralType"},
{ slot: "changeIntegral"},
{ prop: "nowIntegral", label: '剩余积分', align: "center",width: "200px" },
{ slot: "eventDesc"},
]
}
},
created() {
this.$dict.load('integralType').then(() => {
this.getDetail()
this.getIntegralChange()
this.getEventSummary()
let nowTime = dayjs().format('YYYY-MM-DD')
let timeAgo = dayjs().subtract(29, 'day').format('YYYY-MM-DD')
this.startPla = timeAgo
this.endPla = nowTime
})
},
methods: {
// 详情
getDetail() {
this.instance.post(`/app/appintegraluser/girdDetail`,null,{
params: {
id: this.$route.query.id
}
}).then(res=>{
if(res?.data) {
this.data = res.data
}
})
},
// 事件汇总
getEventSummary() {
this.instance.post(`/app/appintegraluser/eventSummary`,null,{
params: {
id: this.$route.query.id,
startTime: this.startTime,
endTime: this.endTime,
}
}).then(res=>{
if(res?.data) {
this.xData = res.data.map(x=> x.eventName)
this.yData = res.data.map(y=> y.totalIntegral)
this.getColEcherts(this.xData, this.yData)
}
})
},
// 余额变动明细
getIntegralChange() {
this.instance.post(`/app/appintegraluser/getChangeDetail`, null, {
params: {
...this.search, //积分类型
total: this.total,
id: this.$route.query.id,
}
}).then(res => {
if(res?.data) {
this.tableData = res.data.records
this.total = res.data.total
}
})
},
timeChange() {
if(this.timeList.length) {
this.startTime = this.timeList[0]
this.endTime = this.timeList[1]
this.getEventSummary()
}
},
getColEcherts(xData, yData) {
let chartDom = document.getElementById('chartDom');
chartDom.style.width = window.innerWidth - 335 + "px";
this.myChart = echarts.init(chartDom);
this.myChart.setOption({
dataZoom: [
{
type: "slider",
xAxisIndex: [0],
filterMode: "filter",
},
],
grid: {
left: '16px',
right: '28px',
bottom: '14px',
top: '30px',
containLabel: true
},
xAxis: {
type: 'category',
data: xData,
},
yAxis: {
type: 'value',
},
series: [
{
data: yData,
type: 'bar',
itemStyle: {
normal: {
color: "#5087ec",
label: {
show: true, //开启显示
position: 'top', //在上方显示
textStyle: {
fontSize: 13,
color: '#666'
}
},
},
},
barWidth: 20,
barGap: '20%',
}
]
}, true);
window.addEventListener("resize", this.onResize)
},
onResize() {
this.myChart.resize()
},
cancel(isRefresh) {
this.$emit('change', {
type: 'gridScoreManage',
isRefresh: !!isRefresh
})
}
},
filters: {
formatTime(num) {
if(num > 0) {
return '+' + num
} else {
return num
}
}
},
mounted() {
this.getColEcherts()
},
destroyed () {
window.removeEventListener('resize', this.onResize)
},
}
</script>
<style lang="scss" scoped>
.gridScoreDetail {
width: 100%;
height: 100%;
padding: 0 20px;
box-sizing: border-box;
overflow-y: scroll;
.card_list {
display: flex;
.card {
flex: 1;
height: 96px;
background: #FFFFFF;
box-shadow: 0px 4px 6px -2px rgba(15,15,21,0.1500);
border-radius: 4px;
margin-right: 20px;
padding: 16px 24px;
box-sizing: border-box;
h2 {
color: #888888;
font-weight: 600;
font-size: 16px;
}
p {
margin-top: 8px;
font-size: 24px;
font-weight: 600;
}
.color1 {
color: #2891FF;
}
.color2 {
color: #22AA99;
}
.color3 {
color: #F8B425;
}
}
.card:last-child {
margin-right: 0;
}
}
.echertsBox {
width: 100%;
margin-top: 20px;
background: #FFFFFF;
box-shadow: 0px 4px 6px -2px rgba(15,15,21,0.1500);
border-radius: 4px;
padding: 16px;
box-sizing: border-box;
.title {
display: flex;
justify-content: space-between;
h4 {
color: #222222;
font-style: 16px;
font-weight: 600;
}
}
.bar_Box {
width: 100%;
#chartDom {
width: 100%;
height: 230px;
margin-top: 16px;
}
}
}
}
</style>

View File

@@ -0,0 +1,361 @@
<template>
<section class="gridScoreManage">
<ai-list>
<template #content>
<ai-search-bar>
<template #left>
<el-button type="primary" size="small" icon="iconfont iconAdd" @click="changeIntegral('',0)">&nbsp;批量调整积分</el-button>
<el-cascader ref="cascader1" clearable v-model="girdIdList" :options="girdOptions" placeholder="所属网格" size="small"
:props="defaultProps" :show-all-levels="false" @change="gridChange"></el-cascader>
</template>
<template #right>
<el-input size="small" placeholder="姓名" v-model="search.userName" clearable
@clear="current = 1, search.userName = '', getTableData()" suffix-icon="iconfont iconSearch"
v-throttle="() => {(current = 1), getTableData();}"/>
<ai-download :instance="instance" url="/app/appintegraluser/girdIntegralExport" :params="search" fileName="网格员积分"
:disabled="tableData.length == 0">
<el-button size="small">导出</el-button>
</ai-download>
</template>
</ai-search-bar>
<ai-table :tableData="tableData" :total="total" :current.sync="current" :size.sync="size"
@getList="getTableData()" :col-configs="colConfigs" :dict="dict" @sort-change="changeTableSort">
<el-table-column slot="options" label="操作" align="center">
<template slot-scope="{ row }">
<el-button type="text" @click="changeIntegral(row,1)">调整积分</el-button>
<el-button type="text" @click="toDetail(row.id)">详情</el-button>
</template>
</el-table-column>
</ai-table>
</template>
</ai-list>
<ai-dialog
title="调整积分"
:visible.sync="dialog"
:destroyOnClose="true"
width="720px"
@onConfirm="onConfirm"
@closed="form={},chooseUserList=[]">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="选择人员" prop="ids">
<ai-person-select :instance="instance" :customClicker="true" :chooseUserList="chooseUserList"
url="/app/appgirdmemberinfo/list" headerTitle="网格员列表"
:isMultiple="true" dialogTitle="选择" @selectPerson="selectPerson" class="aipersonselect">
<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-form-item>
<el-form-item label="调整说明" prop="eventDesc">
<el-input v-model.trim="form.eventDesc" placeholder="请输入..." type="textarea" :rows="4" show-word-limit
maxlength="100"></el-input>
</el-form-item>
<el-form-item label="上传凭证">
<ai-uploader :instance="instance" fileType="file" v-model="form.file" :limit="1"></ai-uploader>
</el-form-item>
<el-form-item label="类型" prop="integralCalcType">
<ai-select v-model="form.integralCalcType" :selectList="dict.getDict('integralCalcType')"/>
</el-form-item>
<el-form-item label="积分" prop="integral">
<el-input v-model.trim="form.integral" placeholder="请输入正数" size="small"></el-input>
</el-form-item>
</el-form>
</ai-dialog>
</section>
</template>
<script>
import { mapState } from "vuex";
export default {
name: "gridScoreManage",
label: "积分管理",
props: {
instance: Function,
dict: Object,
permissions: Function,
},
data() {
return {
search: {
userName: '',
girdId: '',
current: 1,
size: 10,
sortFiled: '',
sortRule: '',
},
girdIdList: [],
tableData: [],
size: 10,
total: 0,
current: 1,
girdList: [],
form: {
ids: [],
eventDesc: "",
enclosure: "", // 附件
integralCalcType: "",
integral: '',
file: [],
},
personList: [],
dialog: false,
girdOptions: [],
defaultProps: {
label: 'girdName',
value: 'id',
checkStrictly: true,
},
chooseUserList: [],
flag: false,
}
},
created() {
this.$dict.load('integralCalcType')
this.getTableData()
this.getGridList()
},
computed: {
...mapState(['user']),
colConfigs() {
return [
{ prop: "userName", label: '姓名', align: "left", },
{ prop: "girdName", label: '所属网格' },
{ prop: "integral", label: '积分余额', align: "center", sortable: "custom" },
{ prop: "totalIntegral", label: '累计积分', align: "center", sortable: "custom" },
{ prop: "usedIntegral", label: '已用积分', align: "center", sortable: "custom" },
{ slot: "options" },
]
},
rules() {
return {
ids: [{required: true, message: '请选择人员', trigger: 'blur'}],
eventDesc: [{required: true, message: '请输入调整说明', trigger: 'blur'}],
integralCalcType: [{required: true, message: '请选择类型', trigger: 'change'}],
integral: [{required: true, message: '请输入积分', trigger: 'blur' },
{pattern: /^([1-9]\d*|0)(\.\d{1,2})?$/, message: '请输入正数且最多只能保留两位小数'}],
}
},
},
methods: {
getTableData() {
this.instance.post(`/app/appintegraluser/integralManager`,null,{
params: {
...this.search,
current: this.current,
size: this.size,
total: this.total
}
}).then(res => {
if(res?.data) {
this.tableData = res.data.records
this.total = res.data.total
}
})
},
selectPerson(val) {
if (val) {
this.personList = val
this.form.ids = [...this.personList.map(e => e.id)]
} else {
this.form.ids = this.chooseUserList.map(e => e.id)
}
},
changeIntegral(row,type) {
if(type==0) {
this.dialog = true
} else if(type ==1) {
this.chooseUserList = [{
id: row.userId,
name: row.userName
}]
this.form.ids = this.chooseUserList.map(e => e.id)
this.dialog = true
}
},
getGridList() {
this.instance.post(`/app/appgirdinfo/listAll3`).then((res) => {
if (res.code == 0) {
this.girdOptions = this.toTree(res.data)
}
})
},
// 转树形结构
toTree(data) {
let result = [];
if (!Array.isArray(data)) {
return result
}
let map = {};
data.forEach(item => {
map[item.id] = item;
});
data.forEach(item => {
let parent = map[item.parentGirdId];
if (parent) {
(parent.children || (parent.children = [])).push(item);
} else {
result.push(item);
}
});
return result;
},
gridChange(val) {
this.girdIdList = val
this.search.girdId = val?.[val.length - 1]
this.$refs.cascader1.dropDownVisible = false;
this.getTableData()
},
changeTableSort(col) {
if(col.prop === 'integral') { // 剩余积分
this.search.sortFiled = 0
if(col.order === 'ascending') {
this.search.sortRule = true
} else if(col.order === 'descending') {
this.search.sortRule = false
} else if(col.order === null) {
this.search.sortRule = ''
}
} else if(col.prop === 'totalIntegral') { // 累计积分
this.search.sortFiled = 1
if(col.order === 'ascending') {
this.search.sortRule = true
} else if(col.order === 'descending') {
this.search.sortRule = false
} else if(col.order === null) {
this.search.sortRule = ''
}
} else if(col.prop === 'usedIntegral') { // 已用积分
this.search.sortFiled = 2
if(col.order === 'ascending') {
this.search.sortRule = true
} else if(col.order === 'descending') {
this.search.sortRule = false
} else if(col.order === null) {
this.search.sortRule = ''
}
}
this.getTableData()
},
onConfirm() {
if(this.flag) return
if(this.form.file?.length) {
this.form.enclosure = this.form.file[0].url
}
this.$refs.form.validate((valid)=> {
if(valid) {
this.flag = true
this.instance.post(`/app/appintegraluser/changeIntegral`,{
ids: this.form.ids,
eventDesc: this.form.eventDesc,
enclosure: this.form.enclosure, // 附件
integralCalcType: this.form.integralCalcType,
integral: this.form.integral,
}).then(res => {
if(res?.code == 0) {
this.$message.success('调整积分成功')
setTimeout(() =>{
this.dialog = false
this.getTableData()
this.flag = false
}, 600)
} else {
this.flag = false
}
})
}
})
},
toDetail(id) {
this.$emit('change', {
type: 'gridScoreDetail',
params: {
id: id
}
})
}
},
}
</script>
<style lang="scss" scoped>
.gridScoreManage {
height: 100%;
::v-deep .ai-dialog .ai-dialog__content {
max-height: 600px!important;
}
.userlist {
display: inline-block;
}
.userlist, .user {
display: inline-block;
}
.user {
position: relative;
width: 70px;
text-align: center;
.remove-icon {
position: absolute;
right: 7px;
top: -4px;
line-height: 1;
padding: 6px 0;
font-size: 16px;
cursor: pointer;
&:hover {
color: crimson;
}
}
img, h2 {
display: block;
width: 40px;
height: 40px;
line-height: 40px;
text-align: center;
margin: 0 auto 4px;
font-size: 14px;
color: #fff;
border-radius: 50%;
}
h2 {
background-color: $primaryColor;
}
span {
color: #666;
font-size: 14px;
white-space: nowrap;
overflow: hidden;
word-break: break-all;
text-overflow: ellipsis;
}
}
::v-deep .selectCont .pagination {
width: 100%!important;
background: pink;
}
}
</style>

View File

@@ -0,0 +1,482 @@
<template>
<section class="gridScoreRules">
<!-- v-if="permissions('app_appvillagerintegralrule_detail')" -->
<ai-list>
<template slot="content">
<ai-search-bar>
<template #left>
<el-button type="primary" icon="iconfont iconAdd" @click="dialog = true">&nbsp;添加</el-button>
<el-cascader size="small" v-model="systemRuleIdList" :options="rulesOps" placeholder="请选择事件/类型" clearable :props="rulesProps"
@change="handleTypeSearch" ref="eventTypeSearch"/>
<ai-select v-model="search.status" @change="(page.current = 1), getList()" placeholder="请选择状态" :selectList="$dict.getDict('integralRuleStatus')">
</ai-select>
</template>
</ai-search-bar>
<ai-table :tableData="tableData" :col-configs="colConfigs" :total="page.total" :dict="dict" :current.sync="page.current" :size.sync="page.size"
@getList="getList()">
<el-table-column slot="integral" label="分值" align="center">
<template slot-scope="{ row }">
<!-- <span v-if="row.integralValueType == 1">
{{ row.integralStart > 0 ? "+" + row.integralStart : row.integralStart }}~{{ row.integralEnd > 0 ? "+" + row.integralEnd : row.integralEnd }}
</span> -->
<span>{{ row.integral > 0 ? "+" : "" }}{{ row.integral }}</span>
</template>
</el-table-column>
<el-table-column slot="options" label="操作" align="center" fixed="right" width="200">
<template slot-scope="{ row }">
<div class="table-options">
<el-button type="text" @click="changeStatus(row.id, 0)" v-if="row.status == 1">停用</el-button>
<el-button type="text" @click="changeStatus(row.id, 1)" v-else>启用</el-button>
<el-button type="text" @click="toEdit(row)">编辑</el-button>
<el-button type="text" @click="remove(row.id)">删除</el-button>
</div>
</template>
</el-table-column>
</ai-table>
</template>
</ai-list>
<!-- <ai-empty v-else>暂无应用权限</ai-empty> -->
<ai-dialog :title="dialogTitle" :visible.sync="dialog" @onConfirm="onConfirm" @closed="closed" width="900px" @open="beforeSelectTree">
<div class="form_div">
<el-form ref="DialogForm" :model="form" :rules="formRules" size="small" label-suffix="" label-width="150px">
<el-form-item label="事件类型" prop="systemRuleId">
<el-cascader v-model="form.systemRuleId" ref="cascaderArr" :props="etOps" clearable placeholder="请选择" @change="handleTypeForm" :options="rulesOps"/>
</el-form-item>
<el-form-item label="自定义事件" v-if="form.systemRuleId == '自定义'" prop="ruleName" :required="form.systemRuleId == '自定义'">
<el-input placeholder="请输入,周期范围内,不填写表示不限制" v-model="form.ruleName" clearable maxlength="10" show-word-limit/>
</el-form-item>
<el-form-item label="规则">
<div>常规</div>
</el-form-item>
<!-- <el-form-item label="规则" prop="ruleType" v-if="form.ruleType>-1" required>
<el-row type="flex" justify="space-between">
<div v-text="$dict.getLabel('integralRuleRuleType',form.ruleType)"/>
<el-button v-if="form.ruleType==1" type="text" icon="iconfont iconAdd"
@click="form.ladderRule.push({viewCount:null,integral:null})">添加
</el-button>
</el-row>
<el-table v-if="form.ruleType==1" :data="form.ladderRule" size="mini" border stripe>
<el-table-column label="查看人数(人)" align="center">
<template slot-scope="{row}">
<el-input class="tableInput" v-model.number="row.viewCount" clearable placeholder="请输入"/>
</template>
</el-table-column>
<el-table-column label="获得积分(分)" align="center">
<template slot-scope="{row}">
<el-input class="tableInput" v-model="row.integral" clearable placeholder="请输入" type="number"
@keyup.native="row.integral=checkIntegral(row.integral)"/>
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="{$index}">
<el-button type="text" @click="handleDelete($index)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-form-item> -->
<el-form-item label="周期范围" prop="scoringCycle">
<ai-select v-model="form.scoringCycle" :selectList="$dict.getDict('integralRuleScoringCycle')"/>
</el-form-item>
<el-form-item label="奖励次数">
<el-input type="number" placeholder="请输入,周期范围内,不填写表示不限制" v-model.number="form.numberLimit" clearable/>
</el-form-item>
<el-form-item label="积分分值" prop="integral">
<el-input placeholder="请输入" v-model="form.integral" clearable/>
</el-form-item>
<el-form-item label="有效范围" prop="validRangeType" required>
<el-radio-group v-model="form.validRangeType">
<el-radio label="0">全局</el-radio>
<el-radio label="1">指定网格</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="生效网格" :prop="form.validRangeType == 1 ? 'validRangeData' : ''"
:rules="[{ required: true, message: '请选择生效网格', trigger: 'change' }, ]" v-if="form.validRangeType == 1">
<ai-dialog-btn dialogTitle="选择网格" append-to-body @onConfirm="getCheckedTree" :customFooter="false" :text="girdInfoList.length ? '重新选择' : '请选择'">
<div class="grid">
<el-tree :data="treeObj.treeList" :props="treeObj.defaultProps" node-key="id" :expand-on-click-node="false">
<template slot-scope="{data}">
<el-row class="fill" type="flex" @click.native.stop="handleTreeChecked(data)">
<div class="fill" v-text="data.girdName"/>
<div class="iconfont iconSuccess color-primary mar-r8" v-if="data.checked"/>
</el-row>
</template>
</el-tree>
</div>
</ai-dialog-btn>
<div v-if="girdInfoList.length">
<span v-for="(e,index) in girdNameList" :key="index" class="mar-r8" v-text="e"/>
</div>
</el-form-item>
</el-form>
</div>
</ai-dialog>
</section>
</template>
<script>
export default {
name: "gridScoreRules",
label: "积分规则",
props: {
instance: Function,
dict: Object,
permissions: Function,
},
data() {
var validcode = (rule, value, callback) => {
if (value) {
if (value != 0) {
if (!/^([+-]?([1-9]{1}\d*)|(0{1}))(\.\d{1,2})?$/.test(value)) {
callback(new Error('请输入积分分值,可输入正数、负数、最多保留两位小数'))
} else {
callback();
}
} else {
callback(new Error('请输入有效的积分分值'));
}
} else {
callback(new Error('请输入积分分值'));
}
}
return {
search: {
status: "",
systemRuleId: "",
ruleName: ""
},
systemRuleIdList: [],
page: {current: 1, size: 10, total: 0},
colConfigs: [
{
prop: "parentRuleName",
label: "类型",
dict: "integralRuleEventType",
},
{prop: "ruleName", label: "事件", dict: "integralRuleEvent"},
{prop: "ruleType", label: "规则", dict: "integralRuleRuleType"},
{
prop: "scoringCycle",
label: "周期范围",
dict: "integralRuleScoringCycle",
render: (h, {row}) => {
return h(
"span",
{},
row.numberLimit.length
? $dict.getLabel("integralRuleScoringCycle", row.scoringCycle)
: $dict.getLabel("integralRuleScoringCycle", row.scoringCycle) +
row.numberLimit +
"次"
);
},
},
{slot: "integral", label: "积分分值", align: "center"},
{
prop: "validRangeType",
label: "有效范围",
formart: (v) => (v == 0 ? "全局" : "指定网格"),
},
{
prop: "status",
label: "状态",
align: "center",
width: 96,
dict: "integralRuleStatus",
},
{slot: "options", label: "操作", align: "center"},
],
tableData: [],
dialog: false,
form: {
ruleType: "0",
systemRuleId: "",
ruleName: "",
scoringCycle: "",
numberLimit: "",
integral: "",
validRangeType: "0",
validRangeData: "",
},
formRules: {
systemRuleId: [
{required: true, message: "请选择事件/类型", trigger: "change"},
],
ruleName: [
{required: true, message: "请输入自定义事件", trigger: "change"},
],
scoringCycle: [
{required: true, message: "请选择周期范围", trigger: "change"},
],
integral: [{required: true, validator: validcode, trigger: "blur"},],
validRangeType: [
{required: true, message: "请选择有效范围", trigger: "change"},
],
},
rulesOps: [],
rulesProps: {
label: "ruleName",
value: "id",
checkStrictly: true,
},
radio: 0,
treeObj: {
treeList: [],
defaultProps: {
label: "girdName",
value: "id",
children: 'children',
isLeaf: 'leaf'
},
},
treeSelected: {},
girdInfoList: [],
rulueType: "0",
girdNameList: [],
list: [],
};
},
created() {
this.$dict.load("integralRuleStatus", "integralRuleRuleType", "integralRuleScoringCycle",
"integralRuleEvent", "integralRuleEventType").then(() => {
this.getList();
this.getRulesList();
});
},
methods: {
getList() {
this.instance
.post(`/app/appintegralrule/list`, null, {
params: {
...this.search,
...this.page,
},
})
.then((res) => {
if (res?.data) {
this.tableData = res.data.records;
this.page.total = res.data.total;
}
});
},
closed() {
this.form = {
ruleType: "0",
systemRuleId: "",
ruleName: "",
scoringCycle: "",
numberLimit: "",
integral: "",
validRangeType: "0",
validRangeData: "",
};
this.girdInfoList = []
this.treeSelected = {}
},
toEdit(row) {
this.form = {...row}
if (this.form?.validRangeData) {
this.girdInfoList = JSON.parse(this.form.validRangeData)
this.girdNameList = this.girdInfoList.map(e => e.girdName)
}
this.$nextTick(() => {
this.dialog = true;
});
},
remove(id) {
this.$confirm("删除后不可恢复,是否要删除该规则?", {
type: "error",
}).then(() => {
this.instance
.post(`/app/appintegralrule/delete?ids=${id}`)
.then((res) => {
if (res.code == 0) {
this.$message.success("删除成功!");
this.getList();
}
});
});
},
changeStatus(id, status) {
let text = status == 1 ? "启用" : "停用";
this.$confirm(`确定${text}该条规则?`).then(() => {
this.instance
.post(`/app/appintegralrule/enableStatus?id=${id}`)
.then((res) => {
if (res.code == 0) {
this.$message.success(`${text}成功!`);
this.getList();
}
});
});
},
onConfirm() {
this.$refs.DialogForm.validate((valid) => {
if (valid) {
let formData = this.$copy(this.form);
// formData.ladderRule = JSON.stringify(formData.ladderRule)
formData.integral = formData.integral || 0;
this.instance
.post(`/app/appintegralrule/addOrUpdate`, formData)
.then((res) => {
if (res.code == 0) {
this.$message.success(
`${this.isEdit ? "编辑成功" : "添加成功"}`
);
this.dialog = false;
this.getList();
this.closed();
this.girdInfoList = []
this.girdNameList = []
}
});
} else {
return false;
}
});
},
handleTypeSearch(v) {
this.systemRuleIdList = v
this.search.systemRuleId = v?.[v.length - 1];
this.search.ruleName = this.$refs.eventTypeSearch.getCheckedNodes()[0]?.label
this.page.current = 1;
this.$refs.eventTypeSearch.dropDownVisible = false;
this.getList();
},
handleTypeForm(v) {
if (this.dialog) {
this.form.systemRuleId = v?.[v.length - 1];
}
},
handleDelete(i) {
this.$confirm("是否要删除该规则?")
.then(() => {
this.form.ladderRule.splice(i, 1);
})
.catch(() => 0);
},
checkIntegral(v) {
return /\.\d{2,}$/.test(v) ? Math.abs(v).toFixed(1) : Math.abs(v);
},
getRulesList() {
this.instance
.post(`/app/appintegralsystemrule/list?current=1&sizes=3000`)
.then((res) => {
if (res?.data) {
this.rulesOps = this.toTree(res.data.records);
this.rulesOps.push({
ruleName: "自定义",
id: "自定义",
});
}
});
},
// 转树形结构
toTree(data) {
let result = [];
if (!Array.isArray(data)) {
return result;
}
let map = {};
data.forEach((item) => {
map[item.id] = item;
});
data.forEach((item) => {
let parent = map[item.parentRuleId];
if (parent) {
(parent.children || (parent.children = [])).push(item);
} else {
result.push(item);
}
});
return result;
},
getCheckedTree() {
const selected = Object.values(this.treeSelected)
if (!selected.length) {
return this.$message.error("请选择网格");
}
this.girdInfoList = selected.map((item) => {
return {...item, checkType: true};
});
let validRangeData = selected.map((e) => ({id: e.id, girdName: e.girdName}))
this.girdNameList = validRangeData.map(e => e.girdName)
this.form.validRangeData = JSON.stringify(validRangeData)
},
beforeSelectTree() {
this.instance.post(`/app/appgirdinfo/listAll3`, null, null).then((res) => {
if (res?.data) {
this.list = res.data.map(e => ({...e, checked: !!this.girdInfoList.find(s => s.id == e.id)}))
this.girdInfoList.map(e => this.treeSelected[e.id] = e)
this.treeObj.treeList = this.$arr2tree(this.list, {parent: 'parentGirdId'})
}
});
},
handleTreeChecked(data) {
this.list.forEach(v => {
return {
...v,
checked: false
}
})
data.checked = !data.checked
if (data.checked) {
this.treeSelected[data.id] = data
} else {
delete this.treeSelected[data.id]
}
}
},
computed: {
isEdit() {
return !!this.form.id;
},
dialogTitle() {
return this.isEdit ? "编辑积分规则" : "添加积分规则";
},
etOps() {
return {
value: "id",
label: "ruleName",
};
},
},
};
</script>
<style lang="scss" scoped>
.gridScoreRules {
height: 100%;
background: #f3f6f9;
::v-deep .ai-list__content--right {
width: 100%;
}
// ::v-deep .searchRightZone {
// display: flex;
// }
::v-deep .ai-dialog {
.el-cascader {
width: 100%;
}
.tableInput {
& > input {
text-align: center;
border: none;
background: transparent;
}
}
}
}
</style>

View File

@@ -0,0 +1,653 @@
<template>
<section class="gridScoreStatistics">
<el-row class="overallStatistics">
<div class="title">
<p>总体统计</p>
<div class="title_right">
<div>
<span v-for="(item,index) in timeCheck" :key="index" :class="type == index? 'active':''"
@click="timeChange(index)">{{ item }}</span>
</div>
<el-cascader ref="cascader1" v-model="girdArr" :options="girdOptions" placeholder="所属网格" size="small"
:props="defaultProps" :show-all-levels="false" @change="gridChange" clearable></el-cascader>
</div>
</div>
<div class="card_list">
<div class="card">
<h2>积分余额汇总
<el-tooltip
placement="right"
style="width: 16px;"
content="截止目前所有网格员剩余可用积分余额的总和">
<i class="el-icon-warning-outline"></i>
</el-tooltip>
</h2>
<p class="color1">{{ data.nowIntegral || 0 }}</p>
</div>
<div class="card">
<h2>发放积分</h2>
<p class="color1">{{ data.addIntegral || 0 }}</p>
</div>
<div class="card">
<h2>消耗积分</h2>
<p class="color1">{{ data.reduceIntegral || 0 }}</p>
</div>
</div>
<div class="echertsBox">
<div class="left_Box">
<p>个人积分排行</p>
<div>
<div id="chart1" style="height: 300px; width: 100%;" v-show="userSortListX.length && userSortListY.length"></div>
<ai-empty v-show="!userSortListX.length && !userSortListY.length" style="height: 200px; width: 100%;" id="empty"></ai-empty>
</div>
</div>
<div class="right_Box">
<p>网格积分排行</p>
<div>
<div id="chart2" style="height: 300px; width: 100%;" v-show="girdSortListX.length && girdSortListY.length"></div>
<ai-empty v-show="!girdSortListX.length && !girdSortListY.length" style="height: 200px; width: 100%;" id="empty"></ai-empty>
</div>
</div>
</div>
</el-row>
<ai-card>
<ai-title slot="title" title="积分明细"/>
<template #content>
<ai-search-bar>
<template #left>
<el-cascader ref="cascader2" v-model="girdIdArr" :options="girdOptions" placeholder="所属网格" size="small"
:props="defaultProps" :show-all-levels="false" clearable @change="gridChangeOpt"></el-cascader>
<ai-select v-model="search.integralType" placeholder="请选择类型" @change="current=1, getTableData()"
:selectList="dict.getDict('integralType')"/>
<el-date-picker v-model="time" size="small" type="daterange" value-format="yyyy-MM-dd"
range-separator="" start-placeholder="开始日期" end-placeholder="结束日期" @change="onChange">
</el-date-picker>
</template>
<template #right>
<el-input size="small" placeholder="请输入姓名" v-model="search.userName" clearable
@clear="current = 1, search.userName = '', getTableData()" suffix-icon="iconfont iconSearch"
v-throttle="() => {(current = 1), getTableData();}" />
</template>
</ai-search-bar>
<ai-table :tableData="tableData" :total="total" :current.sync="current" :size.sync="size"
@getList="getTableData" :col-configs="colConfigs" :dict="dict">
<el-table-column slot="eventDesc" label='事件' align="center" width="400px" show-overflow-tooltip>
<template slot-scope="{ row }">
<span v-if="row.integralRuleId">{{ row.integralRuleName }}</span>
<span v-else>{{ row.eventDesc }}</span>
</template>
</el-table-column>
<el-table-column slot="integralType" label="类型" align="center">
<template slot-scope="{ row }">
<span v-if="row.integralRuleId">{{ row.eventType }}</span>
<span v-else>{{ row.integralRuleName }}</span>
</template>
</el-table-column>
<el-table-column slot="changeIntegral" label="积分变动" align="center">
<template slot-scope="{ row }">
<span v-if="row.integralType == 3">{{ row.changeIntegral | formatTime }}</span>
<span v-if="row.integralType == 0">{{ row.integralCalcType == 0 ? '-' : '+' }}{{ row.changeIntegral }}</span>
</template>
</el-table-column>
<el-table-column slot="options" label="操作" align="center">
<template slot-scope="{ row }">
<el-button type="text" @click="open(row.id)">详情</el-button>
</template>
</el-table-column>
</ai-table>
</template>
</ai-card>
<el-dialog title="详情" :visible.sync="dialog" customFooter width="700">
<ai-detail>
<template #content>
<ai-wrapper>
<ai-info-item label="姓名" :value="details.integralUserName" />
<ai-info-item label="所属网格" :value="details.girdName"/>
<ai-info-item label="事件" isLine :value="details.eventDesc">
<span v-if="details.integralRuleId">{{ details.integralRuleName }}</span>
<span v-else>{{ details.eventDesc }}</span>
</ai-info-item>
<ai-info-item label="时间" isLine :value="details.createTime"/>
<ai-info-item label="积分变动" v-if="details.integralType == 3">
{{ details.changeIntegral | formatTime }}
</ai-info-item>
<ai-info-item label="积分变动" v-if="details.integralType == 0">
{{ details.changeIntegral > 0 ? '+' : '-' }}{{ details.changeIntegral }}
</ai-info-item>
<ai-info-item label="积分余额" :value="details.nowIntegral"/>
<ai-info-item label="凭证" isLine v-if="fileDownLoad.length">
<ai-file-list :fileList="fileDownLoad" style="width: 200px;" :fileOps="{name: 'name'}"></ai-file-list>
</ai-info-item>
</ai-wrapper>
</template>
</ai-detail>
<span slot="footer" class="dialog-footer" center>
<el-button @click="dialog = false" style="width: 92px">关闭</el-button>
</span>
</el-dialog>
<ai-dialog :visible.sync="dialogDate" title="选择时间" width="500px" customFooter>
<el-date-picker v-model="timeList" size="small" type="daterange" value-format="yyyy-MM-dd"
range-separator="" start-placeholder="开始日期" end-placeholder="结束日期">
</el-date-picker>
<el-button slot="footer" @click="selectDete" type="primary">确认</el-button>
</ai-dialog>
</section>
</template>
<script>
import { mapState } from "vuex"
import * as echarts from 'echarts';
export default {
name: "gridScoreStatistics",
label: "积分统计",
props: {
instance: Function,
dict: Object,
permissions: Function,
},
data() {
return {
myChart1: null,
myChart2: null,
tableData: [],
search: {
current: 1,
userName: '',
girdId: '',
integralType: '',
startTime: '',
endTime: '',
},
girdIdArr:[],
total: 0,
size: 10,
current: 1,
girdList: [],
time: [],
timeCheck: ['昨日','近7天','近30天','自定义'],
dialog: false,
dialogDate: false,
timeList: [],
type: '1',
startTime: '',
endTime: '',
data: {},
girdId: '',
girdArr: [],
girdOptions: [],
defaultProps: {
label: 'girdName',
value: 'id',
children: 'children',
checkStrictly: true,
},
details: {},
fileDownLoad: [],
userSortListX: [],
userSortListY: [],
girdSortListX: [],
girdSortListY: [],
}
},
computed: {
...mapState(['user']),
colConfigs() {
return [
{ prop: "integralUserName", label: '姓名', align: "left", width: "200px" },
{ prop: "girdName", label: '所属网格', align: "center", width: "180px" },
{ slot: "eventDesc"},
{ slot: "integralType", label: '类型' },
{ slot: "changeIntegral", label: '积分变动', align: "center", },
{ prop: "nowIntegral", label: '剩余积分', align: "center", },
{ prop: "createTime", label: '时间', align: "center", },
{ slot: "options" }
]
}
},
created() {
this.$dict.load('epidemicDangerousAreaLevel','integralType','integralRuleEvent','integralRuleEventType').then(() => {
this.getStatistics()
this.getGridList()
this.getRanking()
this.getTableData()
})
},
methods: {
// 统计接口
getStatistics() {
this.instance.post('/app/appintegraluser/allGirdIntegral',null, {
params: {
type: this.type,
girdId: this.girdId,
startTime: this.startTime,
endTime: this.endTime,
}
}).then(res => {
if(res?.data) {
this.data = res.data
}
})
},
// 人员、网格排行
getRanking() {
this.instance.post('/app/appintegraluser/userAndGirdIntegralSort',null,{
params: {
type: this.type,
girdId: this.girdId,
startTime: this.startTime,
endTime: this.endTime
}
}).then((res) => {
if(res?.data) {
this.userSortListX = res.data.userSortList.map(e=> e.userName).reverse()
this.userSortListY = res.data.userSortList.map(e=> e.changeIntegral).reverse()
this.girdSortListX = res.data.girdSortList.map(e=> e.girdName).reverse()
this.girdSortListY = res.data.girdSortList.map(e=> e.changeIntegral).reverse()
this.getColEcherts1(this.userSortListX,this.userSortListY)
this.getColEcherts2(this.girdSortListX,this.girdSortListY)
}
})
},
// 积分明细
getTableData() {
this.instance.post('/app/appintegraluser/girdIntegralDetail',null,{
params: {
...this.search,
current: this.current,
size: this.size,
total: this.total,
}
}).then(res => {
if(res?.data) {
this.tableData = res.data.records
this.total = res.data.total
}
})
},
gridChangeOpt(val) {
this.girdIdArr = val
this.search.girdId = val?.[val.length - 1]
this.$refs.cascader2.dropDownVisible = false;
this.getTableData()
},
getColEcherts1(xData,yData) {
let chartDom1 = document.getElementById('chart1');
chartDom1.style.width = (window.innerWidth - 435) / 2 + "px";
this.myChart1 = echarts.init(chartDom1);
this.myChart1.setOption({
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
grid: {
left: '16px',
right: '28px',
bottom: '14px',
top: '16px',
containLabel: true
},
xAxis: {
type: 'value',
boundaryGap: [0, 0.01],
},
yAxis: {
type: 'category',
data: xData,
axisTick: {
show: false,
},
axisLine: {
show: false,
},
},
series: [
{
data: yData,
type: 'bar',
itemStyle: {
normal: {
color: "#5087ec",
label: {
show: true, //开启显示
position: 'right', //在上方显示
textStyle: {
fontSize: 13,
color: '#666'
}
},
},
},
barWidth: 10,
barGap: '20%',
}
]
}, true);
window.addEventListener("resize", this.onResize)
},
getColEcherts2(xData,yData) {
let chartDom2 = document.getElementById('chart2');
chartDom2.style.width = (window.innerWidth - 435) / 2 + "px";
this.myChart2 = echarts.init(chartDom2);
this.myChart2.setOption({
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
grid: {
left: '16px',
right: '28px',
bottom: '14px',
top: '16px',
containLabel: true
},
xAxis: {
type: 'value',
boundaryGap: [0, 0.01],
},
yAxis: {
type: 'category',
data: xData,
axisTick: {
show: false,
},
axisLine: {
show: false,
},
triggerEvent: true,
//设置文本过长超出隐藏...表示
axisLabel:{
margin: 8,
formatter: function(params){
var val=""
if(params.length > 8) {
val = params.substr(0,8)+'...'
return val
} else {
return params;
}
}
},
},
series: [
{
data: yData,
type: 'bar',
itemStyle: {
normal: {
color: "#5087ec",
label: {
show: true, //开启显示
position: 'right', //在右方显示
textStyle: {
fontSize: 13,
color: '#666'
}
},
},
},
barWidth: 10,
barGap: '20%',
}
]
}, true);
window.addEventListener("resize", this.onResize2)
// this.extension(this.myChart2)
},
onResize1() {
this.myChart1.resize()
},
onResize2() {
this.myChart2.resize()
},
gridChange(val) {
this.girdArr = val
this.girdId = val?.[val.length - 1]
this.$refs.cascader1.dropDownVisible = false;
this.getStatistics()
this.getRanking()
},
// 所有网格
getGridList() {
this.instance.post(`/app/appgirdinfo/listAll3`).then((res) => {
if (res?.code == 0) {
this.girdOptions = this.toTree(res.data)
}
})
},
// 转树形结构
toTree(data) {
let result = [];
if (!Array.isArray(data)) {
return result
}
let map = {};
data.forEach(item => {
map[item.id] = item;
});
data.forEach(item => {
let parent = map[item.parentGirdId];
if (parent) {
(parent.children || (parent.children = [])).push(item);
} else {
result.push(item);
}
});
return result;
},
timeChange(index) {
if(index == 3) {
this.dialogDate = true
}
this.type = index
this.getStatistics()
this.getRanking()
},
open(id) {
this.dialog = true
this.getDetail(id)
},
onChange(val) {
this.search.startTime = val?.[0]
this.search.endTime = val?.[1]
this.getTableData()
},
getDetail(id) {
this.instance.post(`/app/appintegraldetail/queryDetailById?id=${id}`).then(res=> {
if(res?.data) {
this.details = res.data
if(res.data.enclosure) {
let str = res.data.enclosure.split('/')
this.fileDownLoad = [{
url:res.data.enclosure,
name: str?.[str.length - 1]
}]
}
}
})
},
selectDete() {
if(!this.timeList || !this.timeList.length) {
return this.$message.error('请选择自定义时间');
}
this.startTime = this.timeList?.[0]
this.endTime = this.timeList?.[1]
this.dialogDate = false
this.getStatistics()
this.getRanking()
},
},
filters: {
formatTime(num) {
if(num > 0) {
return '+' + num
} else {
return num
}
}
},
mounted() {
this.getColEcherts1()
this.getColEcherts2()
},
destroyed () {
window.removeEventListener('resize', this.onResize1)
window.removeEventListener('resize', this.onResize2)
},
}
</script>
<style lang="scss" scoped>
.gridScoreStatistics {
height: 100%;
box-sizing: border-box;
padding-top: 20px;
.overallStatistics {
width: 100%;
margin-bottom: 16px;
padding: 20px;
box-sizing: border-box;
background: #FFF;
.title {
width: 100%;
display: flex;
justify-content: space-between;
margin-bottom: 16px;
p {
font-size: 16px;
font-family: MicrosoftYaHeiSemibold;
color: #222222;
font-weight: 600;
}
.title_right {
display: flex;
align-items: center;
span {
display: inline-block;
width: 70px;
height: 32px;
line-height: 32px;
border-radius: 2px;
border: 1px solid #D0D4DC;
margin-right: 8px;
text-align: center;
cursor: pointer;
}
.active {
color: #2266FF;
border: 1px solid #2266FF;
}
}
}
.card_list {
display: flex;
.card {
flex: 1;
height: 96px;
background: #F9F9F9;
border-radius: 2px;
margin-right: 20px;
padding: 16px 24px;
box-sizing: border-box;
h2 {
color: #888888;
font-weight: 600;
font-size: 16px;
}
p {
margin-top: 8px;
font-size: 24px;
font-weight: 600;
}
.color1 {
color: #2891FF;
}
.color2 {
color: #22AA99;
}
.color3 {
color: #F8B425;
}
}
.card:last-child {
margin-right: 0;
}
}
.echertsBox {
width: 100%;
margin-top: 20px;
background: #FFF;
display: flex;
.left_Box {
margin-right: 16px;
flex: 1;
}
.right_Box {
width: 100%;
flex: 1;
}
.left_Box,
.right_Box {
background: #F9F9F9;
box-shadow: 0px 4px 6px -2px rgba(15,15,21,0.1500);
border-radius: 4px;
padding: 16px;
box-sizing: border-box;
#chart1,
#chart2 {
width: 100%;
height: 300px;
}
p {
font-weight: 600;
}
}
}
}
// .chartCss {
// position: absolute;
// color: black;
// background:white;
// font-family: Aril;
// font-size: 12px;
// padding: 5px;
// display: inline;
// }
::v-deep .el-dialog__footer {
text-align: center;
}
::v-deep .el-dialog__header {
border-bottom: 1px solid #DDD;
}
::v-deep .ai-detail {
background: #FFF;
}
}
</style>

View File

@@ -0,0 +1,62 @@
<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: 'AppIntegralAudit',
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>

View File

@@ -0,0 +1,239 @@
<template>
<ai-detail class="audit">
<template slot="title">
<ai-title title="详情" isShowBack isShowBottomBorder @onBackClick="cancel(true)">
</ai-title>
</template>
<template slot="content">
<ai-card title="基本信息">
<template #content>
<ai-wrapper
label-width="120px">
<ai-info-item label="申请人" :value="info.residentName"></ai-info-item>
<ai-info-item label="申请时间" :value="info.createTime"></ai-info-item>
<!-- <ai-info-item label="积分类型" :value="dict.getLabel('atWillReportType', info.applyIntegralType)"></ai-info-item> -->
<ai-info-item label="申请描述" :value="info.description" isLine></ai-info-item>
<ai-info-item label="联系电话" isLine :value="info.residentPhone"></ai-info-item>
<ai-info-item label="图片" isLine>
<ai-uploader v-model="info.applyFiles" disabled></ai-uploader>
</ai-info-item>
</ai-wrapper>
</template>
</ai-card>
<ai-card title="处理结果" v-if="info.auditStatus !== '0'">
<div slot="content" style="margin-top: 16px;margin-bottom:24px">
<ai-wrapper
label-width="120px">
<ai-info-item label="审核结果" :value="info.auditStatus === '1' ? '通过' : '拒绝'" isLine></ai-info-item>
<ai-info-item label="审核意见" v-if="info.auditStatus === '2'" isLine :value="info.auditOpinion"></ai-info-item>
<!-- <ai-info-item label="积分规则类别" v-if="info.auditStatus === '1'" :value="dict.getLabel('atWillReportType', info.auditIntegralType)"></ai-info-item>-->
<!-- <ai-info-item label="积分规则事项" v-if="info.auditStatus === '1'" :value="info.auditRuleName"></ai-info-item>-->
<ai-info-item label="积分调整" isLine v-if="info.auditStatus === '1'"
:value="(info.auditIntegral >= 0 ? info.auditIntegral : info.auditIntegral) + '分'"></ai-info-item>
<ai-info-item label="审核人" :value="info.auditUserName"></ai-info-item>
<ai-info-item label="审核时间" :value="info.auditTime"></ai-info-item>
</ai-wrapper>
</div>
</ai-card>
<ai-dialog
:visible.sync="isShow"
width="800px"
@close="onClose"
title="事件审核"
@onConfirm="onConfirm">
<el-form class="ai-form" label-width="120px" :model="form" ref="form">
<el-form-item label="是否通过审核" prop="pass" style="width: 100%;" :rules="[{ required: true, message: '请选择是否通过审核' }]">
<el-radio-group v-model="form.pass" @change="onStatusChange">
<el-radio label="0"></el-radio>
<el-radio label="1"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="form.pass === '1'" label="积分调整" prop="auditIntegral" style="width: 100%;" :rules="[{ required: true, message: '请输入积分调整' }]">
<el-input v-model.number="form.auditIntegral" clearable placeholder="请输入积分调整" @keyup.native="form.auditIntegral=Math.abs(form.auditIntegral)"/>
</el-form-item>
<!-- <el-form-item v-if="form.pass === '1'" label="积分规则类别" prop="auditRuleId" style="width: 100%;" :rules="[{ required: true, message: '' }]">-->
<!-- <div class="flex-warpper">-->
<!-- <el-form-item label-width="0" prop="auditIntegralType" :rules="[{ required: true, message: '请选择积分规则类别' }]">-->
<!-- <ai-select-->
<!-- v-model="form.auditIntegralType"-->
<!-- clearable-->
<!-- style="width: 180px;"-->
<!-- placeholder="请选择积分规则类别"-->
<!-- :selectList="dict.getDict('atWillReportType')"-->
<!-- @change="onChange">-->
<!-- </ai-select>-->
<!-- </el-form-item>-->
<!-- <el-form-item style="margin: 0 10px;" prop="auditRuleId" :rules="[{ required: true, message: '请选择积分规则事项' }]">-->
<!-- <ai-select-->
<!-- v-model="form.auditRuleId"-->
<!-- clearable-->
<!-- style="width: 180px;"-->
<!-- placeholder="请选择积分规则事项"-->
<!-- :selectList="ruleList">-->
<!-- </ai-select>-->
<!-- </el-form-item>-->
<!-- <span>{{ integralText }}</span>-->
<!-- </div>-->
<!-- </el-form-item>-->
<el-form-item label="审核意见" v-if="form.pass === '0'" prop="opinion" style="width: 100%;" :rules="[{ required: true, message: '请输入审核意见' }]">
<el-input type="textarea" :rows="5" :maxlength="200" v-model="form.opinion" clearable placeholder="请输入审核意见" show-word-limit></el-input>
</el-form-item>
</el-form>
</ai-dialog>
</template>
<template #footer>
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="isShow = true" v-if="info.auditStatus === '0'">审核</el-button>
</template>
</ai-detail>
</template>
<script>
export default {
name: 'Detail',
props: {
instance: Function,
dict: Object,
params: Object
},
data() {
const validatorRules = function (rule, value, callback) {
if (value === '') {
callback(new Error('请输入联系方式'))
} else if (!/^1\d{10}$/.test(value)) {
callback(new Error('手机号格式错误'))
} else {
callback()
}
}
return {
total: 0,
info: {
auditStatus: '0'
},
id: '',
isShow: false,
form: {
auditIntegralType: '',
auditRuleId: '',
opinion: '',
pass: ''
},
ruleList: []
}
},
computed: {
integralText() {
if (!this.form.auditRuleId) {
return ''
}
const integral = this.ruleList.filter(v => v.dictValue === this.form.auditRuleId)[0].integral
return integral >= 0 ? `+${integral}` : `${integral}`
}
},
created() {
if (this.params && this.params.id) {
this.id = this.params.id
this.dict.load(['atWillReportType', 'auditStatus']).then(() => {
this.getInfo(this.params.id)
})
}
},
methods: {
getInfo(id) {
this.instance.post(`/app/appvillagerintegraldeclare/queryDetailById?id=${id}`).then(res => {
if (res.code === 0) {
this.info = res.data
}
})
},
onStatusChange() {
this.$refs.form.clearValidate()
},
onClose() {
this.form.auditIntegralType = ''
this.form.auditRuleId = ''
this.form.pass = ''
this.form.opinion = ''
this.id = ''
},
onConfirm() {
this.$refs.form.validate(v => {
if (v) {
this.instance.post('/app/appvillagerintegraldeclare/examine', null, {
params: {
...this.form,
id: this.params.id,
}
}).then(res => {
if (res.code == 0) {
this.isShow = false
this.getInfo(this.params.id)
this.$message.success('审核成功!')
}
})
}
})
},
onChange(e) {
this.form.auditRuleId = ''
this.instance.post(`/app/appvillagerintegralrule/list?size=1000&classification=${e}`).then(res => {
if (res?.code == 0) {
this.ruleList = res.data.records.filter(v => v.ruleStatus === '1').map(v => {
return {
dictName: v.ruleName,
dictValue: v.id,
ruleName: v.ruleName,
integral: v.integral
}
})
}
})
},
cancel(isRefresh) {
this.$emit('change', {
type: 'list',
isRefresh: !!isRefresh
})
}
}
}
</script>
<style scoped lang="scss">
.audit {
.flex-warpper {
display: flex;
align-items: center;
::v-deep .el-form-item .el-form-item__content {
margin-left: 0 !important;
}
::v-deep .ai-select {
margin: 0 !important;
}
::v-deep .el-form-item {
width: auto;
margin-bottom: 0;
&:last-child {
margin-right: 10px;
}
}
}
}
</style>

View File

@@ -0,0 +1,237 @@
<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="content">
<ai-search-bar>
<template #left>
<ai-select
v-model="search.applyIntegralType"
clearable
placeholder="请选择积分类型"
:selectList="dict.getDict('atWillReportType')"
@change="search.current = 1, getList()">
</ai-select>
<ai-select
v-model="search.auditStatus"
clearable
placeholder="请选择审核状态"
:selectList="dict.getDict('auditStatus')"
@change="search.current = 1, getList()">
</ai-select>
<el-date-picker
value-format="yyyy-MM-dd"
v-model="search.createTimeStart"
type="date"
size="small"
unlink-panels
placeholder="选择开始日期"
@change="search.current = 1, getList()" />
<el-date-picker
value-format="yyyy-MM-dd"
v-model="search.createTimeEnd"
type="date"
size="small"
unlink-panels
placeholder="选择结束日期"
@change="search.current = 1, getList()" />
</template>
<template #right>
<el-input
v-model="search.residentName"
size="small"
placeholder="请输入姓名"
clearable
v-throttle="() => {search.current = 1, getList()}"
@clear="search.current = 1, search.residentName = '', 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: 8px;"
: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>
</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,
residentName: '',
applyIntegralType: '',
areaId: '',
auditStatus: '',
createTimeStart: '',
createTimeEnd: ''
},
dictList: [{
dictName: '否',
dictValue: '0'
}, {
dictName: '是',
dictValue: '1'
}],
info: {},
colConfigs: [
{ prop: 'residentName', label: '申请人' },
{ prop: 'residentPhone', align: 'center', label: '联系电话' },
{ prop: 'createTime', align: 'center', label: '申请时间' },
{ prop: 'applyIntegralType', align: 'center', label: '积分类型', formart: v => this.dict.getLabel('atWillReportType', v) },
{ prop: 'auditStatus', align: 'center', label: '状态', formart: v => v ? this.dict.getLabel('auditStatus', v) : '-' },
{ prop: 'auditUserName', align: 'center', label: '审批人' },
{ prop: 'auditTime', align: 'center', label: '审批时间' }
],
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(['atWillReportType', 'auditStatus']).then(() => {
this.getList()
})
},
methods: {
getList () {
this.instance.post(`/app/appvillagerintegraldeclare/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
})
},
toDetail (id) {
this.$emit('change', {
type: 'Detail',
params: {
id: id || ''
}
})
},
changeArea () {
this.search.current = 1
this.$nextTick(() => {
this.getList()
})
}
}
}
</script>
<style scoped lang="scss">
.list {
::v-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>

View File

@@ -0,0 +1,76 @@
<template>
<ai-list>
<template slot="title">
<ai-title title="积分维护" :isShowBottomBorder="false" :instance="instance" :isShowArea="true" v-model="areaId"
@change="changeArea"></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 :is="tab.comp" v-if="currIndex === String(i)" :ref="tab.name"
:areaId="areaId" :instance="instance" :dict="dict" :permissions="permissions"/>
</el-tab-pane>
</el-tabs>
</template>
</ai-list>
</template>
<script>
import pointsDeclaration from "./pointsDeclaration.vue"
import pointsDetails from "./pointsDetails.vue"
import pointsAppeal from './pointsAppeal'
import {mapState} from 'vuex'
import scoreChange from "./scoreChange";
export default {
name: 'AppScoreManage',
label: "积分维护",
components: {pointsDeclaration, pointsDetails, pointsAppeal, scoreChange},
props: {
instance: Function,
dict: Object,
permissions: Function
},
computed: {
...mapState(['user']),
tabs() {
return [
{
label: "积分明细",
name: "pointsDetails",
comp: pointsDetails,
permission: "app_apppartyfee_statistics",
},
{
label: "积分调整",
name: "scoreChange",
comp: scoreChange,
permission: "",
},
]
}
},
created() {
this.areaId = this.user.info.areaId
this.dict.load("integralCalcType")
},
methods: {
changeArea() {
this.$nextTick(() => {
this.$refs[this.tabs[Number(this.currIndex)].name][0].getList()
})
}
},
data() {
return {
activeName: "pointsDeclaration",
currIndex: '0',
areaId: ''
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,611 @@
<template>
<section class="pointsDeclaration">
<ai-list isTabs>
<template slot="content">
<ai-search-bar bottomBorder>
<template slot="left">
<el-button type="primary" icon="iconfont iconAdd" @click="onAdd" v-if="$permissions('app_appvillagerintegraldeclare_edit')">代申诉</el-button>
<el-button icon="iconfont iconEdit" @click="batchAduit()" :disabled="!Boolean(selectionList.length)" v-if="$permissions('app_appvillagerintegraldeclare_edit')">批量审核</el-button>
<ai-select
v-model="search.status"
@change="page.current = 1, getList()"
placeholder="发布状态"
:selectList="dict.getDict('integralDeclareStatus')">
</ai-select>
<div class="times_div">
<p class="times">申诉时间</p>
<el-date-picker
v-model="search.declareTimeStart"
type="date"
size="small"
@change="page.current = 1,getList()"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="开始日期">
</el-date-picker>
<el-date-picker
v-model="search.declareTimeEnd"
type="date"
size="small"
@change="page.current = 1,getList()"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="结束日期">
</el-date-picker>
</div>
</template>
<template slot="right">
<el-input
v-model="search.familyName"
class="search-input"
size="mini"
placeholder="申诉人/申诉对象/..."
clearable
v-throttle="() => {page.current = 1, getList()}"
@clear="page.current = 1, getList()"
suffix-icon="iconfont iconSearch" />
</template>
</ai-search-bar>
<ai-table
:tableData="tableData"
:col-configs="colConfigs"
:total="page.total"
:current.sync="page.current"
:size.sync="page.size"
@getList="getList"
@selection-change="handleSelectionChange"
>
<el-table-column slot="selection" type="selection" width="55" :selectable="(row, index)=>{
if(row.status==0){
return true
}else{
return false
}
}"></el-table-column>
<el-table-column slot="options" label="操作" align="center">
<template slot-scope="{ row }">
<span
class="iconfont iconEdit icon-color89B"
v-if="row.status === '0'&&$permissions('app_appvillagerintegraldeclare_edit')"
title="编辑"
@click="toEdit(row)"
></span>
<span
class="iconfont iconShow icon-color89B"
v-if="row.status !== '0'&&$permissions('app_appvillagerintegraldeclare_detail')"
title="详情"
@click="toEdit(row)"
></span>
<!-- <span
class="iconfont iconDelete icon-color89B"
v-if="$permissions('app_appofficialdocumentinfo_del')"
title="删除"
@click="remove(row.id)"
></span> -->
</template>
</el-table-column>
</ai-table>
</template>
</ai-list>
<ai-dialog
title="积分代申诉"
:visible.sync="dialog.visibleAdd"
:customFooter="true"
:destroyOnClose="true"
width="720px"
@close="init('ruleForm')"
>
<div class="form_div">
<el-form
ref="ruleForm"
:model="dialogInfo"
:rules="formRules"
size="small"
label-suffix=""
label-width="140px"
>
<el-form-item label="代申诉家庭" prop="users">
<ai-person-select :customClicker="true" :isMultiple="true" :chooseUserList.sync="dialogInfo.users" :instance="instance" url="/app/appvillagerintegralfamilymember/list" >
<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-form-item>
<el-form-item label="代申诉说明" prop="declareDescription">
<el-input type="textarea" :rows="3" placeholder="请输入…" maxlength="100" show-word-limit v-model="dialogInfo.declareDescription"></el-input>
</el-form-item>
<el-form-item label="照片" prop="fileList">
<div class="upload">
<ai-uploader :instance="instance" v-model="dialogInfo.fileList" :limit="9" ></ai-uploader>
</div>
</el-form-item>
</el-form>
</div>
<div class="dialog-footer" slot="footer">
<el-button @click="dialog.visibleAdd=false" size="medium">取消</el-button>
<el-button @click="declare('ruleForm')" type="primary" size="medium">提交</el-button>
</div>
</ai-dialog>
<ai-dialog
title="申诉审核"
:visible.sync="dialog.visibleDetail"
:customFooter="true"
:destroyOnClose="true"
width="720px"
@close="init('rules')"
>
<div class="form_content" v-if="!isBatch">
<div class="form_flex form_info">
<div>
<span class="form_label">申诉人</span>
<span class="form_value">{{rowInfo.declareName}}</span>
</div>
<div>
<span class="form_label">申诉对象</span>
<span class="form_value">{{rowInfo.declareObjName}}</span>
</div>
<div>
<span class="form_label">户主</span>
<span class="form_value">{{rowInfo.familyName}}</span>
</div>
</div>
<div class="form_info">
<span class="form_label">申诉说明</span>
<span class="form_value">{{rowInfo.declareDescription}}</span>
</div>
<div class="form_info">
<span class="form_label">申诉时间</span>
<span class="form_value">{{rowInfo.declareTime}}</span>
</div>
<div class="form_info">
<span class="form_label">照片</span>
<span class="form_value">
<ai-uploader :disabled="true" :instance="instance" v-model="rowInfo.fileList" :limit="9" ></ai-uploader>
</span>
</div>
</div>
<div class="form_div">
<el-form
ref="rules"
:model="dialogDetail"
:rules="formRules"
size="small"
label-suffix=""
v-show="rowInfo.status==0"
label-width="90px"
>
<el-form-item label="类型" prop="doType">
<el-radio-group v-model="dialogDetail.doType" @change="changeDoType">
<el-radio label="1">加分</el-radio>
<el-radio label="0">扣分</el-radio>
<el-radio label="2">拒绝</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="事项" prop="ruleId" v-if='dialogDetail.doType!=2'>
<el-select v-model="dialogDetail.ruleId" placeholder="请选择..." @change="ruleChange">
<el-option
v-for="(item,i) in rulesList"
:key="i"
:label="item.ruleName"
:value="item.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="积分" prop="doIntegral" v-if='dialogDetail.doType!=2'>
<el-col :span="1.5" style="margin-right: 8px;">{{dialogDetail.doType==0? '减少' :'增加'}}</el-col>
<el-col :span="6" style="margin-right: 8px;width:120px;"><el-input type="number" v-model="dialogDetail.doIntegral" :placeholder="placeholder" :disabled="integralEdit"></el-input></el-col>
<el-col :span="1" style="margin-right: 8px;"></el-col>
</el-form-item>
<el-form-item label="备注说明">
<el-input type="textarea" :rows="3" maxlength="100" placeholder="请输入…" show-word-limit v-model="dialogDetail.remark"></el-input>
</el-form-item>
</el-form>
<ai-wrapper
label-width="70px"
v-if="rowInfo.status!=0"
:columnsNumber="1">
<ai-info-item label="类型:"><span :style="{color:colorList[rowInfo.status]}" >{{dict.getLabel('integralDeclareStatus', rowInfo.status)}}</span></ai-info-item>
<ai-info-item label="事项:" v-if='rowInfo.doType!=2'><span >{{rowInfo.ruleName}}</span></ai-info-item>
<ai-info-item label="积分:" v-if='rowInfo.doType!=2'>{{rowInfo.doType==0? '减少' :'增加'}}<span style="color:#2266FF">{{Math.abs(rowInfo.doIntegral)}}</span></ai-info-item>
<ai-info-item label="备注说明:"><span>{{rowInfo.remark||'-'}}</span></ai-info-item>
</ai-wrapper>
</div>
<div class="dialog-footer" slot="footer" v-if="rowInfo.status==0">
<el-button @click="dialog.visibleDetail=false" size="medium">取消</el-button>
<el-button @click="onConfirm('rules')" type="primary" size="medium">提交</el-button>
</div>
</ai-dialog>
</section>
</template>
<script>
import {mapState} from 'vuex';
export default {
name: "pointsAppeal",
props: {
instance: Function,
dict: Object,
bizType:String,
areaId:String
},
data() {
var integral = (rule, value, callback) => {
if (value) {
if (/^[1-9]\d*$/.test(value)) {
if(!this.integralEdit){
if(Number(value)>=this.sectionNum.min&&Number(value)<=this.sectionNum.max){
callback();
}else{
callback(new Error(`请输入${this.sectionNum.min}${this.sectionNum.max}之间的正整数积分`));
}
}else{
callback();
}
} else {
callback(new Error('请输入正整数'));
}
} else {
callback(new Error('请输入正整数'));
}
};
return {
search: {
status:'',
familyName:'',
declareTimeStart:null,
declareTimeEnd:null
},
page:{
current: 1,
size: 10,
total:0
},
colConfigs: [
{ slot: "selection", label: "", align: "center" },
{ prop: "declareName", label: "申诉人", align: "center" },
{ prop: "declareObjName", label: "申诉对象", align: "center",hide:this.bizType==1 },
{
prop: "familyName",
label: "户主",
},
{
prop: "declareDescription",
label: "申诉说明",
align: "left",
width:300
},
{
prop: "declareTime",
label: "申诉时间",
align: "left",
width:150
},
{
prop: "declareName",
label: "操作人",
align: "center",
},
{
prop: "status",
label: "状态",
align: "center",
render: (h, {row}) => {
return h('span', {style: {color: this.dict.getColor('integralDeclareStatus', row.status)}}, this.dict.getLabel('integralDeclareStatus', row.status))
},
},
{ slot: "options", label: "操作", align: "center" },
],
tableData: [],
dialog: {
visibleAdd: false,
visibleDetail: false,
title:'积分代申诉'
},
dialogInfo: {
users: [],
reportIds:[],
declareDescription: "",
fileList: [],
},
dialogDetail: {
doType: '1',
ruleId: '',
doIntegral: '',
remark: '',
aduitIds:[],
ruleName:''
},
isBatch:false,
rulesList:[],
rowInfo:{},
formRules: {
users: [{ required: true, message: "请选择人员", trigger: "change" },],
declareDescription: [{ required: true, message: "代申诉说明", trigger: "blur" }],
// fileList: [{ required: true, message: "请上传照片", trigger: "blur" },],
ruleId: [{ required: true, message: "请选择事项", trigger: "blur" }],
doIntegral: [{ required: true, validator: integral, trigger: "blur" }],
doType:[{ required: true, message: "请选择类型", trigger: "change" }]
},
selectionList:[],
integralEdit:false,
sectionNum:{
min:null,
max:null
},
placeholder:'请输入...'
};
},
computed:{
colorList(){
return {
'0':'#FF8822',
'1':'#2EA222',
'2':'#FF4466'
}
}
},
created() {
this.dict
.load([
'integralDeclareStatus',
'integralDeclareDoType'
]).then(() => {
this.getList();
});
},
methods: {
getList() {
this.instance.post(`/app/appvillagerintegraldeclare/list`, null, {
params: {
...this.search,
...this.page,
bizType:this.bizType,
areaId:this.areaId
},
})
.then((res) => {
if (res.code == 0) {
this.tableData = res.data.records;
this.page.total = res.data.total;
}
});
},
handleSelectionChange(val){
this.selectionList=val
this.dialogDetail.aduitIds=[];
val.forEach(e=>{
this.dialogDetail.aduitIds.push(e.id);
})
},
// getSelect(val){
// for(let e of val){
// this.dialogInfo.reportIds.push(e.id)
// }
// },
getColor(status){
return this.dict.getColor('integralDeclareStatus', status)
},
onChange(val){
},
declare(formName){
this.dialogInfo.reportIds=[];
for(let e of this.dialogInfo.users){
this.dialogInfo.reportIds.push(e.id)
};
this.$refs[formName].validate((valid) => {
if (valid) {
this.instance.post("/app/appvillagerintegraldeclare/addOrUpdate", {
...this.dialogInfo,
bizType:this.bizType
}, null).then(res => {
if (res.code==0) {
this.dialog.visibleAdd=false;
this.getList();
}
})
} else {
return false;
}
});
},
init(formName){
this.$refs[formName].clearValidate();
this.dialogDetail = {
doType: '1',
ruleId: '',
doIntegral: '',
remark: '',
aduitIds:[],
ruleName:''
}
this.dialogInfo= {
users: [],
reportIds:[],
declareDescription: "",
fileList: [],
};
this.rulesList = [];
},
//批量审核
batchAduit(){
this.isBatch=true;
this.rowInfo.status=0;
this.dialog.visibleDetail = true;
this.getRules('1')
},
getRowDetail(row){
this.instance.post(`/app/appvillagerintegraldeclare/queryDetailById`, null, {
params: {
id:row.id
},
}).then((res) => {
if (res.code == 0) {
this.rowInfo = {...res.data}
this.dialog.visibleDetail = true;
this.dialogDetail.aduitIds=[];
this.dialogDetail.aduitIds.push(row.id);
}
});
},
toEdit(row) {
this.isBatch=false;
this.getRowDetail(row);
this.getRules('1')
},
changeDoType(val){
this.dialogDetail.ruleId="";
this.dialogDetail.ruleName = "";
this.dialogDetail.doIntegral = "";
this.placeholder = '请输入...';
this.$refs.rules.clearValidate();
this.getRules(val)
},
ruleChange(val){
let item = this.rulesList.find(e => e.id == val);
this.dialogDetail.doIntegral='';
this.$refs.rules.clearValidate();
if(item){
//固定区间
this.dialogDetail.ruleName = item.ruleName;
if(item.integralValueType==0){
this.dialogDetail.doIntegral = Math.abs(item.integral);
this.integralEdit = true;
}else{
this.integralEdit = false;
if(Math.abs(item.integralEnd)>Math.abs(item.integralStart)){
this.sectionNum.min = Math.abs(item.integralStart);
this.sectionNum.max = Math.abs(item.integralEnd);
}else{
this.sectionNum.max = Math.abs(item.integralStart);
this.sectionNum.min = Math.abs(item.integralEnd);
}
this.placeholder = `${this.sectionNum.min}~${this.sectionNum.max}`
}
}
},
//事项查询
getRules(integralType){
this.instance.post(`/app/appvillagerintegralrule/list`, null, {
params: {
integralType,
size:10000000
},
}).then((res) => {
if (res.code == 0) {
this.rulesList = res.data.records.filter(e=> e.ruleStatus == 1);
}
});
},
remove(id) {
this.$confirm("确定删除该公文及其相关的流转信息?").then(() => {
this.instance
.post(`/app/appofficialdocumentinfo/delete?ids=${id}`)
.then((res) => {
if (res.code == 0) {
this.$message.success("删除成功!");
this.getList();
}
});
});
},
onReset() {
Object.keys(this.search).forEach(e => {
this.search[e] = "";
});
this.search.declareTimeStart = null;
this.search.declareTimeEnd = null;
this.getList();
},
onAdd() {
this.dialog.visibleAdd = true;
},
onConfirm(formName) {
this.$refs[formName].validate(v =>{
if(v){
this.instance.post("/app/appvillagerintegraldeclare/aduit", {
...this.dialogDetail,
}, null).then(res => {
if (res.code==0) {
this.dialog.visibleDetail=false;
this.$message.success("提交成功!");
this.dialogDetail.aduitIds=[];
this.getList();
}
})
}else{
return false
}
})
},
},
};
</script>
<style lang="scss">
.pointsDeclaration {
height: 100%;
overflow: auto;
background: #f3f6f9;
.times_div{
display: flex;
align-items: center;
.times{
display: block;
width: 72px;
height: 30px;
line-height: 30px;
text-align: center;
background: #F5F5F5;
border-radius: 2px 0px 0px 2px;
border: 1px solid #D0D4DC;
font-size: 14px;
color:#666666;
}
}
.form_content{
border-bottom:1px solid #eee;
.form_flex{
display: flex;
div{
flex: 1;
}
}
.form_info{
margin-bottom: 8px;
}
.form_label{
display: inline-block;
color: #999;
vertical-align: top;
}
.form_value{
display: inline-block;
color: #333;
width: calc(100% - 80px);
}
}
.form_div{
padding-top:24px;
}
.status-0 {
color: #ff8822;
}
.status-1 {
color: #2266ff;
}
.status-2 {
color: #999999;
}
}
</style>

View File

@@ -0,0 +1,603 @@
<template>
<section class="pointsDeclaration">
<ai-list isTabs>
<template slot="content">
<ai-search-bar bottomBorder>
<template slot="left">
<el-button type="primary" icon="iconfont iconAdd" @click="onAdd" v-if="$permissions('app_appvillagerintegraldeclare_edit')">代申报</el-button>
<el-button icon="iconfont iconEdit" @click="batchAduit()" :disabled="!Boolean(selectionList.length)"v-if="$permissions('app_appvillagerintegraldeclare_edit')">批量审核</el-button>
<ai-select
v-model="search.status"
@change="page.current = 1, getList()"
placeholder="发布状态"
:selectList="dict.getDict('integralDeclareStatus')">
</ai-select>
<div class="times_div">
<p class="times">申报时间</p>
<el-date-picker
v-model="search.declareTimeStart"
type="date"
size="small"
@change="page.current = 1,getList()"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="开始日期">
</el-date-picker>
<el-date-picker
v-model="search.declareTimeEnd"
type="date"
size="small"
@change="page.current = 1,getList()"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="结束日期">
</el-date-picker>
</div>
</template>
<template slot="right">
<el-input
v-model="search.familyName"
class="search-input"
size="mini"
placeholder="申诉人/申诉对象/..."
clearable
v-throttle="() => {page.current = 1, getList()}"
@clear="page.current = 1, getList()"
suffix-icon="iconfont iconSearch" />
</template>
</ai-search-bar>
<ai-table
:tableData="tableData"
:col-configs="colConfigs"
:total="page.total"
:current.sync="page.current"
:size.sync="page.size"
@getList="getList"
@selection-change="handleSelectionChange">
<el-table-column slot="selection" type="selection" width="55" :selectable="(row, index)=>{
if(row.status==0){
return true
}else{
return false
}
}"></el-table-column>
<el-table-column slot="options" label="操作" align="center">
<template slot-scope="{ row }">
<div class="table-options">
<el-button
type="text"
:disabled="row.status === '0' || $permissions('app_appvillagerintegraldeclare_edit')"
title="编辑"
@click="toEdit(row)">
编辑
</el-button>
<el-button
type="text"
:disabled="$permissions('app_appvillagerintegraldeclare_detail')"
title="详情"
@click="toEdit(row)">
详情
</el-button>
</div>
</template>
</el-table-column>
</ai-table>
</template>
</ai-list>
<ai-dialog
title="积分代申报"
:visible.sync="dialog.visibleAdd"
:customFooter="true"
:destroyOnClose="true"
width="720px"
@close="init('ruleForm')">
<div class="form_div">
<el-form
ref="ruleForm"
:model="dialogInfo"
:rules="formRules"
size="small"
label-suffix=""
label-width="140px">
<el-form-item label="代申报家庭" prop="users">
<ai-person-select :customClicker="true" :isMultiple="true" :chooseUserList.sync="dialogInfo.users" :instance="instance" url="/app/appvillagerintegralfamilymember/list" >
<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-form-item>
<el-form-item label="代申报说明" prop="declareDescription">
<el-input type="textarea" :rows="3" placeholder="请输入…" maxlength="100" show-word-limit v-model="dialogInfo.declareDescription"></el-input>
</el-form-item>
<el-form-item label="照片" prop="fileList">
<div class="upload">
<ai-uploader :instance="instance" v-model="dialogInfo.fileList" :limit="9" ></ai-uploader>
</div>
</el-form-item>
</el-form>
</div>
<div class="dialog-footer" slot="footer">
<el-button @click="dialog.visibleAdd=false" size="medium">取消</el-button>
<el-button @click="declare('ruleForm')" type="primary" size="medium">提交</el-button>
</div>
</ai-dialog>
<ai-dialog
title="申报审核"
:visible.sync="dialog.visibleDetail"
:customFooter="true"
:destroyOnClose="true"
width="720px"
@close="init('rules')">
<div class="form_content" v-if="!isBatch">
<div class="form_flex form_info">
<div>
<span class="form_label">申报人</span>
<span class="form_value">{{rowInfo.declareName}}</span>
</div>
<div>
<span class="form_label">申报对象</span>
<span class="form_value">{{rowInfo.declareObjName}}</span>
</div>
<div>
<span class="form_label">户主</span>
<span class="form_value">{{rowInfo.familyName}}</span>
</div>
</div>
<div class="form_info">
<span class="form_label">申报说明</span>
<span class="form_value">{{rowInfo.declareDescription}}</span>
</div>
<div class="form_info">
<span class="form_label">申报时间</span>
<span class="form_value">{{rowInfo.declareTime}}</span>
</div>
<div class="form_info">
<span class="form_label">照片</span>
<span class="form_value">
<ai-uploader :disabled="true" :instance="instance" v-model="rowInfo.fileList" :limit="9" ></ai-uploader>
</span>
</div>
</div>
<div class="form_div">
<el-form
ref="rules"
:model="dialogDetail"
:rules="formRules"
size="small"
label-suffix=""
v-show="rowInfo.status==0"
label-width="90px"
>
<el-form-item label="类型" prop="doType">
<el-radio-group v-model="dialogDetail.doType" @change="changeDoType">
<el-radio label="1">加分</el-radio>
<el-radio label="0">扣分</el-radio>
<el-radio label="2">拒绝</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="事项" prop="ruleId" v-if='dialogDetail.doType!=2'>
<el-select v-model="dialogDetail.ruleId" placeholder="请选择..." @change="ruleChange">
<el-option
v-for="(item,i) in rulesList"
:key="i"
:label="item.ruleName"
:value="item.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="积分" prop="doIntegral" v-if='dialogDetail.doType!=2'>
<el-col :span="1.5" style="margin-right: 8px;">{{dialogDetail.doType==0? '减少' :'增加'}}</el-col>
<el-col :span="6" style="margin-right: 8px;width:120px;"><el-input type="number" v-model="dialogDetail.doIntegral" :placeholder="placeholder" :disabled="integralEdit"></el-input></el-col>
<el-col :span="1" style="margin-right: 8px;"></el-col>
</el-form-item>
<el-form-item label="备注说明">
<el-input type="textarea" :rows="3" maxlength="100" placeholder="请输入…" show-word-limit v-model="dialogDetail.remark"></el-input>
</el-form-item>
</el-form>
<ai-wrapper
label-width="70px"
v-if="rowInfo.status!=0"
:columnsNumber="1">
<ai-info-item label="类型:"><span :style="{color:colorList[rowInfo.status]}" >{{dict.getLabel('integralDeclareStatus', rowInfo.status)}}</span></ai-info-item>
<ai-info-item label="事项:" v-if='rowInfo.doType!=2'><span >{{rowInfo.ruleName}}</span></ai-info-item>
<ai-info-item label="积分:" v-if='rowInfo.doType!=2'>{{rowInfo.doType==0? '减少' :'增加'}}<span style="color:#2266FF">{{Math.abs(rowInfo.doIntegral)}}</span></ai-info-item>
<ai-info-item label="备注说明:"><span>{{rowInfo.remark||'-'}}</span></ai-info-item>
</ai-wrapper>
</div>
<div class="dialog-footer" slot="footer" v-if="rowInfo.status==0">
<el-button @click="dialog.visibleDetail=false" size="medium">取消</el-button>
<el-button @click="onConfirm('rules')" type="primary" size="medium">提交</el-button>
</div>
</ai-dialog>
</section>
</template>
<script>
import {mapState} from 'vuex';
export default {
name: "pointsDeclaration",
props: {
instance: Function,
dict: Object,
bizType:String,
areaId:String
},
data() {
var integral = (rule, value, callback) => {
if (value) {
if (/^[1-9]\d*$/.test(value)) {
if(!this.integralEdit){
if(Number(value)>=this.sectionNum.min&&Number(value)<=this.sectionNum.max){
callback();
}else{
callback(new Error(`请输入${this.sectionNum.min}${this.sectionNum.max}之间的正整数积分`));
}
}else{
callback();
}
} else {
callback(new Error('请输入正整数'));
}
} else {
callback(new Error('请输入正整数'));
}
};
return {
search: {
status:'',
familyName:'',
declareTimeStart:null,
declareTimeEnd:null
},
page:{
current: 1,
size: 10,
total:0
},
colConfigs: [
{ slot: "selection", label: "" },
{ prop: "declareName", label: "申报人", align: "center" },
{ prop: "declareObjName", label: "申报对象", align: "center",hide:this.bizType==1 },
{
prop: "familyName",
label: "户主",
},
{
prop: "declareDescription",
label: "申诉说明",
align: "left",
width:300
},
{
prop: "declareTime",
label: "申报时间",
align: "left",
width:150
},
{
prop: "declareName",
label: "操作人",
align: "center",
},
{
prop: "status",
label: "状态",
align: "center",
render: (h, {row}) => {
return h('span', {style: {color: this.dict.getColor('integralDeclareStatus', row.status)}}, this.dict.getLabel('integralDeclareStatus', row.status))
},
},
{ slot: "options", label: "操作", align: "center" },
],
tableData: [],
dialog: {
visibleAdd: false,
visibleDetail: false,
title:'积分代申报'
},
dialogInfo: {
users: [],
reportIds:[],
declareDescription: "",
fileList: [],
},
dialogDetail: {
doType: '1',
ruleId: '',
doIntegral: '',
remark: '',
aduitIds:[],
ruleName:''
},
isBatch:false,
rulesList:[],
rowInfo:{},
formRules: {
users: [{ required: true, message: "请选择人员", trigger: "change" },],
declareDescription: [{ required: true, message: "代申报说明", trigger: "blur" }],
// fileList: [{ required: true, message: "请上传照片", trigger: "blur" },],
ruleId: [{ required: true, message: "请选择事项", trigger: "blur" }],
doIntegral: [{ required: true, validator: integral, trigger: "blur" }],
doType:[{ required: true, message: "请选择类型", trigger: "change" }]
},
selectionList:[],
integralEdit:false,
sectionNum:{
min:null,
max:null
},
placeholder:'请输入...'
};
},
computed:{
colorList(){
return {
'0':'#FF8822',
'1':'#2EA222',
'2':'#FF4466'
}
}
},
created() {
this.dict
.load([
'integralDeclareStatus',
'integralDeclareDoType'
]).then(() => {
this.getList();
});
},
methods: {
getList() {
this.instance.post(`/app/appvillagerintegraldeclare/list`, null, {
params: {
...this.search,
...this.page,
bizType:this.bizType,
areaId:this.areaId
},
})
.then((res) => {
if (res.code == 0) {
this.tableData = res.data.records;
this.page.total = res.data.total;
}
});
},
handleSelectionChange(val){
this.selectionList=val
this.dialogDetail.aduitIds=[];
val.forEach(e=>{
this.dialogDetail.aduitIds.push(e.id);
})
},
// getSelect(val){
// for(let e of val){
// this.dialogInfo.reportIds.push(e.id)
// }
// },
getColor(status){
return this.dict.getColor('integralDeclareStatus', status)
},
onChange(val){
},
declare(formName){
this.dialogInfo.reportIds=[];
for(let e of this.dialogInfo.users){
this.dialogInfo.reportIds.push(e.id)
};
this.$refs[formName].validate((valid) => {
if (valid) {
this.instance.post("/app/appvillagerintegraldeclare/addOrUpdate", {
...this.dialogInfo,
bizType:this.bizType
}, null).then(res => {
if (res.code==0) {
this.dialog.visibleAdd=false;
this.getList();
}
})
} else {
return false;
}
});
},
init(formName){
this.$refs[formName].clearValidate();
this.dialogDetail = {
doType: '1',
ruleId: '',
doIntegral: '',
remark: '',
aduitIds:[],
ruleName:''
}
this.dialogInfo= {
users: [],
reportIds:[],
declareDescription: "",
fileList: [],
};
this.rulesList = [];
},
//批量审核
batchAduit(){
this.isBatch=true;
this.rowInfo.status=0;
this.dialog.visibleDetail = true;
this.getRules('1')
},
getRowDetail(row){
this.instance.post(`/app/appvillagerintegraldeclare/queryDetailById`, null, {
params: {
id:row.id
},
}).then((res) => {
if (res.code == 0) {
this.rowInfo = {...res.data}
this.dialog.visibleDetail = true;
this.dialogDetail.aduitIds=[];
this.dialogDetail.aduitIds.push(row.id);
}
});
},
toEdit(row) {
this.isBatch=false;
this.getRowDetail(row);
this.getRules('1')
},
changeDoType(val){
this.dialogDetail.ruleId="";
this.dialogDetail.ruleName = "";
this.dialogDetail.doIntegral = "";
this.placeholder = '请输入...';
this.$refs.rules.clearValidate();
this.getRules(val)
},
ruleChange(val){
let item = this.rulesList.find(e => e.id == val);
this.dialogDetail.doIntegral='';
this.$refs.rules.clearValidate();
if(item){
//固定区间
this.dialogDetail.ruleName = item.ruleName;
if(item.integralValueType==0){
this.dialogDetail.doIntegral = Math.abs(item.integral);
this.integralEdit = true;
}else{
this.integralEdit = false;
if(Math.abs(item.integralEnd)>Math.abs(item.integralStart)){
this.sectionNum.min = Math.abs(item.integralStart);
this.sectionNum.max = Math.abs(item.integralEnd);
}else{
this.sectionNum.max = Math.abs(item.integralStart);
this.sectionNum.min = Math.abs(item.integralEnd);
}
this.placeholder = `${this.sectionNum.min}~${this.sectionNum.max}`
}
}
},
//事项查询
getRules(integralType){
this.instance.post(`/app/appvillagerintegralrule/list`, null, {
params: {
integralType,
size:10000000
},
}).then((res) => {
if (res.code == 0) {
this.rulesList = res.data.records.filter(e=> e.ruleStatus == 1);
}
});
},
remove(id) {
this.$confirm("确定删除该公文及其相关的流转信息?").then(() => {
this.instance
.post(`/app/appofficialdocumentinfo/delete?ids=${id}`)
.then((res) => {
if (res.code == 0) {
this.$message.success("删除成功!");
this.getList();
}
});
});
},
onReset() {
Object.keys(this.search).forEach(e => {
this.search[e] = "";
});
this.search.declareTimeStart = null;
this.search.declareTimeEnd = null;
this.getList();
},
onAdd() {
this.dialog.visibleAdd = true;
},
onConfirm(formName) {
this.$refs[formName].validate(v =>{
if(v){
this.instance.post("/app/appvillagerintegraldeclare/aduit", {
...this.dialogDetail,
}, null).then(res => {
if (res.code==0) {
this.dialog.visibleDetail=false;
this.$message.success("提交成功!");
this.dialogDetail.aduitIds=[];
this.getList();
}
})
}else{
return false
}
})
},
},
};
</script>
<style lang="scss">
.pointsDeclaration {
height: 100%;
overflow: auto;
background: #f3f6f9;
.times_div{
.times{
display: block;
width: 72px;
height: 30px;
line-height: 30px;
text-align: center;
background: #F5F5F5;
border-radius: 2px 0px 0px 2px;
border: 1px solid #D0D4DC;
font-size: 14px;
color:#666666;
}
}
.form_content{
border-bottom:1px solid #eee;
.form_flex{
display: flex;
div{
flex: 1;
}
}
.form_info{
margin-bottom: 8px;
}
.form_label{
display: inline-block;
color: #999;
vertical-align: top;
}
.form_value{
display: inline-block;
color: #333;
width: calc(100% - 80px);
}
}
.form_div{
padding-top:24px;
}
.status-0 {
color: #ff8822;
}
.status-1 {
color: #2266ff;
}
.status-2 {
color: #999999;
}
}
</style>

View File

@@ -0,0 +1,219 @@
<template>
<section class="pointsDetails">
<ai-list isTabs>
<template slot="content">
<ai-search-bar bottomBorder>
<template slot="left">
<el-date-picker size="small" v-model="searchDotime" type="daterange" range-separator="至" @change="timeChange"
start-placeholder="开始日期" end-placeholder="结束日期" value-format="yyyy-MM-dd HH:mm:ss" format="yyyy-MM-dd"></el-date-picker>
</template>
<template slot="right">
<el-input
v-model="search.familyName"
class="search-input"
size="small"
placeholder="对象、户主、事件类型"
clearable
v-throttle="() => {search.current = 1, getList()}"
@clear="search.current = 1, getList()"
suffix-icon="iconfont iconSearch"/>
</template>
</ai-search-bar>
<ai-table
:tableData="tableData"
:col-configs="colConfigs"
:total="total" :dict="dict"
:current.sync="search.current"
:size.sync="search.size"
@getList="getList">
<el-table-column slot="changeIntegral" label="积分" align="center">
<template slot-scope="{ row }">
<span>{{ row.integralCalcType == 1 ? '+' : '-' }}{{ row.changeIntegral }}</span>
</template>
</el-table-column>
<el-table-column slot="options" label="操作" align="center" fixed="right" width="120">
<template slot-scope="{ row }">
<el-button
type="text"
title="详情"
:disabled="!$permissions('app_appvillagerintegraldetail_detail')"
@click="viewItem(row)">
详情
</el-button>
</template>
</el-table-column>
</ai-table>
</template>
</ai-list>
<ai-dialog title="详情" :visible.sync="dialog" :customFooter="true" :destroyOnClose="true" width="720px">
<ai-wrapper>
<ai-info-item label="户主:" :value="dialogInfo.familyName"/>
<ai-info-item label="对象:" :value="dialogInfo.residentName"/>
<ai-info-item label="事件:" :value="dialogInfo.eventDesc" isLine/>
<ai-info-item label="时间:" :value="dialogInfo.doTime" isLine/>
<ai-info-item label="积分:">
{{ dialogInfo.changeIntegral >= 0 ? '增加' : '减少' }}
<span style="color:#26f" v-text="Math.abs(dialogInfo.changeIntegral)"/>
</ai-info-item>
<ai-info-item label="积分余额:" :value="dialogInfo.nowIntegral"/>
</ai-wrapper>
<div class="dialog-footer" slot="footer">
<el-button @click="dialog=false">关闭</el-button>
</div>
</ai-dialog>
</section>
</template>
<script>
export default {
name: "pointsDeclaration",
props: {
instance: Function,
dict: Object,
areaId: String
},
data() {
return {
searchDotime: [],
search: {
current: 1,
size: 10,
familyName: '',
doTimeStart: null,
doTimeEnd: null
},
total: 10,
colConfigs: [
{prop: "residentName", label: "对象", width: 160},
{prop: "familyName", label: "户主", align: "center", width: 160},
{prop: "eventDesc", label: "事件", "show-overflow-tooltip": true, width: 420},
{prop: "doTime", label: "时间", width: 200},
{prop: "type", label: "类型", width: 100, dict: "integralDetailType"},
{slot: "changeIntegral", label: "积分", width: 100},
{slot: "options", label: "操作", align: "center"},
],
tableData: [],
dialog: false,
dialogInfo: {},
};
},
mounted() {
this.$dict
.load([
"integralDeclareDoType",
"integralDetailType",
])
.then(() => {
this.getList();
});
},
methods: {
getList() {
this.instance.post(`/app/appvillagerintegraldetail/list`, null, {
params: {
...this.search,
areaId: this.areaId,
},
})
.then((res) => {
if (res.code == 0) {
this.tableData = res.data.records;
this.total = res.data.total;
}
});
},
timeChange() {
if (this.searchDotime) {
this.search.doTimeStart = this.searchDotime[0]
this.search.doTimeEnd = this.searchDotime[1]
} else {
this.search.doTimeStart = null
this.search.doTimeEnd = null
}
this.search.current = 1
this.getList()
},
viewItem(row) {
this.dialog = true
this.instance.post(`/app/appvillagerintegraldetail/queryDetailById?id=${row.id}`, null, {}).then((res) => {
if (res?.data) {
this.dialogInfo = res.data
}
});
},
onReset() {
this.search.current = 1
this.search.doTimeStart = null
this.search.doTimeEnd = null
this.search.familyName = ''
this.searchDotime = []
this.getList();
},
},
};
</script>
<style lang="scss">
.pointsDetails {
height: 100%;
background: #f3f6f9;
overflow: auto;
.form_content {
.form_flex {
display: flex;
div {
flex: 1;
}
}
.form_info {
margin-bottom: 8px;
}
.form_label {
display: inline-block;
color: #999;
vertical-align: top;
width: 70px;
text-align: right;
}
.form_value {
display: inline-block;
color: #333;
width: calc(100% - 70px);
// img {
// width: 100px;
// height: 100px;
// margin: 0 8px 8px 0;
// }
}
}
.form_div {
padding-top: 24px;
border-top: 1px solid #eee;
}
.status-0 {
color: #FF4466;
}
.status-1 {
color: #2EA222;
}
.status-2 {
color: #999999;
}
}
</style>

View File

@@ -0,0 +1,147 @@
<template>
<div class="scoreChange">
<ai-list isTabs>
<template slot="content">
<ai-search-bar bottomBorder>
<template slot="left">
<el-button type="primary" icon="iconfont iconAdd" @click="dialog=true"
:disabled="!permissions('app_appvillagerintegraldetail_change')">添加
</el-button>
<ai-import :instance="instance" :dict="dict" name="积分调整" type="appvillagerintegraldetail"
v-if="permissions('app_appvillagerintegraldetail_change')" @success="getList"/>
</template>
</ai-search-bar>
<ai-table
:tableData="tableData"
:col-configs="colConfigs"
:total="page.total" :dict="dict"
:current.sync="page.current"
:size.sync="page.size"
@getList="getList">
</ai-table>
</template>
</ai-list>
<ai-dialog
title="添加积分调整"
:visible.sync="dialog"
:destroyOnClose="true"
width="720px"
@onConfirm="onConfirm"
@closed="form={}">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="选择人员" prop="residentId">
<ai-person-select :instance="instance" :customClicker="true"
:url="'/app/appresident/list?areaId=' + user.info.areaId"
:isMultiple="false" dialogTitle="选择" @selectPerson="selectPerson">
<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-form-item>
<el-form-item label="调整说明" prop="eventDesc">
<el-input v-model.trim="form.eventDesc" placeholder="请输入..." type="textarea" :rows="4" show-word-limit
maxlength="100"></el-input>
</el-form-item>
<el-form-item label="类型" prop="integralCalcType">
<ai-select v-model="form.integralCalcType" :selectList="dict.getDict('integralCalcType')"/>
</el-form-item>
<el-form-item label="积分" prop="changeIntegral">
<el-input v-model.trim.num="form.changeIntegral" placeholder="请输入正数" size="small"></el-input>
</el-form-item>
</el-form>
</ai-dialog>
</div>
</template>
<script lang="jsx">
import {mapState} from "vuex"
export default {
name: "scoreChange",
props: {
instance: Function,
dict: Object,
permissions: Function,
areaId: String
},
data() {
return {
tableData: [],
page: {
current: 1,
size: 10,
total: 10
},
form: {},
dialog: false,
personList: [],
}
},
computed: {
...mapState(["user"]),
rules() {
return {
residentId: [{required: true, message: '请选择人员', trigger: 'blur'},],
eventDesc: [{required: true, message: '请输入调整说明', trigger: 'blur'},],
integralCalcType: [{required: true, message: '请选择类型', trigger: 'change'},],
changeIntegral: [{required: true, validator: (r, v, cb) => v > 0 ? cb() : cb("请输入正数")}],
}
},
colConfigs() {
return [
{prop: "residentName", label: "姓名"},
{prop: "eventDesc", label: "调整说明"},
{prop: "integralCalcType", label: "类型", dict: "integralCalcType", align: 'center'},
{prop: "changeIntegral", label: "积分", align: "center", render: (h, {row}) => h('p',{textAlign:'center'}, `${row.integralCalcType > 0 ? '+' : '-'}${row.changeIntegral}`)},
{prop: "doTime", label: "操作时间"},
{prop: "createUserName", label: "操作人", align: "center"},
]
}
},
methods: {
selectPerson(val) {
if (val) {
this.form.residentId = val.id
this.personList = [{...val}]
} else {
this.form.residentId = ""
this.personList = []
}
},
onConfirm() {
this.$refs['form'].validate(valid => {
if (valid) {
this.instance.post(`/app/appvillagerintegraldetail/changeIntegral`, this.form).then(res => {
if (res.code == 0) {
this.$message.success("添加成功")
this.dialog = false
this.getList()
}
})
}
})
},
getList() {
this.instance.post(`/app/appvillagerintegraldetail/list`, null, {
params: {...this.page, areaId: this.areaId, type: 0}
}).then(res => {
if (res?.data) {
this.tableData = res.data.records
this.page.total = res.data.total
}
})
}
},
created() {
this.getList()
}
}
</script>
<style lang="scss" scoped>
.scoreChange {
height: 100%;
overflow: auto;
}
</style>

View File

@@ -0,0 +1,328 @@
<template>
<section class="scoreFamily">
<ai-list v-show="!detailShow">
<template slot="title">
<ai-title title="家庭积分" :isShowBottomBorder="true" :instance="instance" :isShowArea="true" @change="getList()" v-model="areaId"></ai-title>
</template>
<template slot="content">
<ai-search-bar bottomBorder>
<template slot="left">
<el-select size="small" v-model="searchObj.isPositive" placeholder="积分是否大于0" clearable @change="page.current = 1,getList()">
<el-option
v-for="(item,i) in isPositiveList"
:key="i"
:label="item.dictName"
:value="item.dictValue">
</el-option>
</el-select>
</template>
<template slot="right">
<el-input
v-model="searchObj.con"
size="small"
placeholder="户主姓名"
v-throttle="() => {page.current = 1, getList()}"
@clear="page.current = 1, searchObj.con = '', getList()"
clearable
suffix-icon="iconfont iconSearch" />
</template>
</ai-search-bar>
<ai-search-bar class="mt10">
<template slot="left">
<ai-download :instance="instance" type="primary" url="/app/appvillagerintegraldetail/listExport" :params="params" fileName="家庭积分"></ai-download>
</template>
</ai-search-bar>
<ai-table
:tableData="tableData"
:col-configs="colConfigs"
:total="page.total"
ref="aitableex"
:current.sync="page.current"
:size.sync="page.size"
@getList="getList">
<el-table-column label="操作" slot="options" fixed="right" align="center" width="180">
<template v-slot="{row}">
<div class="table-options">
<el-button type="text" title="家庭成员" @click="familyMember(row)" :disabled="!$permissions('app_appvillagerintegralfamilymember_edit')">家庭成员</el-button>
<el-button type="text" :disabled="!$permissions('app_appvillagerintegralfamily_detail')" title="详情" @click="goDetail(row)">详情</el-button>
</div>
</template>
</el-table-column>
</ai-table>
</template>
</ai-list>
<detail v-if="detailShow" @goBack="goBack" :detailInfo='detailInfo' :instance='instance' :dict='dict'></detail>
<ai-dialog class="family-list"
title="成员列表"
:visible.sync="addMemberVisible"
:customFooter="true"
:destroyOnClose="true"
width="780px">
<ai-table
:tableData="familyList"
:col-configs="familycolConfigs"
:total="familyPage.total"
:current.sync="familyPage.current"
:size.sync="familyPage.size"
:isShowPagination="false"
@getList="familyMember(rowInfo)">
<el-table-column label="与户主关系" slot="householdRelation" align="center" width="120">
<template v-slot="{row}">
<span v-if="row.householdName == 1">户主</span>
<span v-else>{{dict.getLabel('householdRelation', row.householdRelation)}}</span>
</template>
</el-table-column>
<el-table-column label="类型" slot="personType" align="center" width="120">
<template v-slot="{row}">户籍居民</template>
</el-table-column>
<el-table-column label="身份证号" slot="idNumber" align="center" width="165">
<template v-slot="{row}">
<ai-id mode="show" :show-eyes="false" :value="row.idNumber"/>
</template>
</el-table-column>
</ai-table>
<div class="dialog-footer" slot="footer">
<el-button @click="addMemberVisible=false" size="medium"> </el-button>
</div>
</ai-dialog>
</section>
</template>
<script>
import {mapState} from 'vuex';
import detail from './detail'
export default {
name: 'AppScoreFamily',
label: "家庭积分",
props: {
instance: Function,
dict: Object,
permissions: Function
},
components: {detail},
data() {
return {
areaId: '',
searchObj: {
personType: '',
villageGroup: '',
status: '',
con: '',
isPositive: '',
},
isPositiveList: [{
dictName: '是',
dictValue: '1'
}, {
dictName: '否',
dictValue: '0'
}],
page: {
current: 1,
size: 10,
total: 0
},
familyPage: {
current: 1,
size: 100,
total: 0
},
exportParams: {},
tableData: [],
dialog: {
title: '添加家庭',
visible: false
},
dialogInfo: {
personType: '0',
name: '',
idNumber: '',
phone: '',
villageGroup: '',
status: '',
areaId: '',
householdRelation: '',
avatar: ''
},
addMemberVisible: false,
detailShow: false,
personUrl: '',
familyList: [],
familyId: '',
detailInfo: {},
rowInfo: {}
}
},
computed: {
...mapState(['user']),
params () {
return {
...this.searchObj,
areaId: this.areaId,
exportType: 0
}
},
colConfigs() {
return [
{
prop: 'name',
label: '户主',
},
{
prop: 'phone',
align: 'center',
label: '联系电话',
},
{
prop: 'householdAreaName',
align: 'center',
label: '所在村',
},
{
prop: 'familyIntegral',
align: 'center',
label: '家庭积分',
},
{
prop: 'familyUsedIntegral',
align: 'center',
label: '已用积分',
},
{
prop: 'familySurplusIntegral',
align: 'center',
label: '剩余积分',
},
{
prop: 'familyNum',
align: 'center',
label: '成员数',
},
]
},
familycolConfigs() {
return [
// {
// prop: 'householdRelation',
// align: 'center',
// label: '与户主关系',
// render(h, {row}) {
// return h('span', {}, _.$dict.getLabel('householdRelation', row.householdRelation))
// }
// },
{
slot: 'householdRelation',
},
{
prop: 'residentType',
align: 'center',
label: '类型',
formart: v => this.dict.getLabel('residentType', v)
},
{
prop: 'name',
align: 'center',
label: '姓名',
},
{
prop: 'idNumber',
align: 'center',
slot: 'idNumber',
label: '身份证号',
width: 165,
},
{
prop: 'phone',
align: 'center',
label: '联系电话',
width: 120,
}
]
},
},
created() {
this.areaId = this.user.info.areaId;
this.dict.load('integralVillageGroup', 'integralRuleStatus', 'householdRelation', 'residentType');
this.getList();
},
methods: {
getList() {
this.instance.post("/app/appresident/familyIntegral", null, {
params: {
...this.searchObj,
...this.page,
areaId: this.areaId
}
}).then(res => {
if (res.code == 0) {
this.tableData = res.data.records
this.page.total = res.data.total
}
})
},
familyMember(row) {
this.rowInfo = {...row}
this.familyId = row.id;
this.instance.post(`/app/appresident/detail?id=${row.id}`).then(res => {
if (res.code == 0) {
this.familyList = res.data.family;
this.familyPage.total = res.data.family.length;
this.addMemberVisible = true;
}
})
},
goBack() {
this.detailShow = false;
},
goDetail(row) {
this.detailInfo = {...row};
this.detailShow = true;
}
}
}
</script>
<style lang="scss" scoped>
.scoreFamily {
height: 100%;
background: #f3f6f9;
overflow: auto;
.form_div {
width: 380px;
}
.add_btn {
color: #5088FF;
font-size: 14px;
line-height: 36px;
text-align: right;
span {
cursor: pointer;
}
span:nth-child(2) {
margin-left: 4px;
}
}
.iconfont {
cursor: pointer;
}
.iconAll_Profile {
padding: 0 8px;
}
.family-list{
::v-deep .el-table--small{
font-size: 14px!important;
}
}
}
</style>

View File

@@ -0,0 +1,144 @@
<template>
<ai-detail class="family_detail">
<template slot="title">
<ai-title title="余额明细" :isShowBack="true" :isShowBottomBorder="true" @onBackClick="$emit('goBack')"></ai-title>
</template>
<template slot="content">
<div class="detail-info">
<div class="detail-info__item">
<h2>户主</h2>
<span>{{ detailInfo.name }}</span>
</div>
<div class="detail-info__item">
<h2>累计积分</h2>
<span style="color: #2266FF;">{{ detailInfo.familyIntegral || 0 }}</span>
</div>
<div class="detail-info__item">
<h2>剩余积分</h2>
<span style="color: #2266FF;">{{ detailInfo.familySurplusIntegral || 0 }}</span>
</div>
<div class="detail-info__item">
<h2>已消费</h2>
<span>{{ detailInfo.familyUsedIntegral || 0 }}</span>
</div>
</div>
<ai-card title="余额变动明细">
<template slot="right">
<ai-download
:instance="instance"
url="/app/appvillagerintegraldetail/export"
:disabled="!Boolean(tableData.length)"
:params="{familyId:detailInfo.id,type}"
fileName="余额变动明细">
<el-button type="text" icon="iconfont iconExported">导出</el-button>
</ai-download>
</template>
<template #content>
<ai-search-bar>
<template #left>
<ai-select v-model="type" placeholder="请选择类型" @change="page.current=1,getList()"
:selectList="dict.getDict('integralDetailType')"/>
</template>
</ai-search-bar>
<ai-table :tableData="tableData" :col-configs="colConfigs"
:total="page.total" border :dict="dict" :current.sync="page.current" :size.sync="page.size" @getList="getList"/>
</template>
</ai-card>
</template>
</ai-detail>
</template>
<script>
export default {
name: 'balance',
props: {
detailInfo: {
type: Object,
require: true
},
instance: Function,
dict: Object
},
data() {
return {
page: {
current: 1,
size: 10,
total: 0
},
type: "",
tableData: []
}
},
created() {
this.dict.load('integralDetailType')
this.getList()
},
computed: {
colConfigs() {
return [
{prop: 'doTime', label: '时间', width: 200},
{prop: "type", label: "类型", dict: "integralDetailType", align: 'center'},
{prop: 'changeIntegral', align: 'center', label: '变动积分', render: (h, {row}) => h('p', `${row.integralCalcType == 1 ? '+' : '-'}${row.changeIntegral}`)},
{prop: 'nowIntegral', align: 'center', label: '剩余积分'},
{prop: 'eventDesc', label: '事件', width: 500}
]
}
},
methods: {
getList() {
this.instance.post('/app/appvillagerintegraldetail/list', null, {
params: {...this.page, familyId: this.detailInfo.id, type: this.type}
}).then(res => {
if (res?.data) {
this.tableData = res.data.records
this.page.total = res.data.total
}
})
}
}
}
</script>
<style lang="scss" scoped>
.family_detail {
height: 100%;
background-color: #fff;
.detail-info {
display: flex;
align-items: center;
margin-bottom: 20px;
.detail-info__item {
flex: 1;
height: 96px;
margin-right: 20px;
padding: 16px 24px;
background: #FFFFFF;
box-shadow: 0 4px 6px -2px rgba(15, 15, 21, 0.15);
border-radius: 4px;
&:last-child {
margin-right: 0;
}
h2 {
margin-bottom: 8px;
color: #888888;
font-size: 16px;
font-weight: bold;
}
span {
display: block;
line-height: 32px;
font-size: 24px;
font-weight: bold;
color: #222;
}
}
}
}
</style>

View File

@@ -0,0 +1,408 @@
<template>
<section class="scoreFamily">
<ai-list v-show="!detailShow">
<template slot="title">
<ai-title title="个人积分" :isShowBottomBorder="true" :instance="instance" :isShowArea="true" @change="getList()" v-model="areaId"></ai-title>
</template>
<template slot="content">
<ai-search-bar bottomBorder>
<template slot="left">
<el-select size="small" v-model="searchObj.householdName" placeholder="是否户主" clearable @change="page.current = 1,getList()">
<el-option
v-for="(item,i) in householdNameList"
:key="i"
:label="item.dictName"
:value="item.dictValue">
</el-option>
</el-select>
<el-select size="small" v-model="searchObj.isPositive" placeholder="积分是否大于0" clearable @change="page.current = 1,getList()">
<el-option
v-for="(item,i) in isPositiveList"
:key="i"
:label="item.dictName"
:value="item.dictValue">
</el-option>
</el-select>
</template>
<template slot="right">
<el-input
v-model="searchObj.con"
size="small"
placeholder="个人姓名"
v-throttle="() => {page.current = 1, getList()}"
@clear="page.current = 1, searchObj.con = '', getList()"
clearable
suffix-icon="iconfont iconSearch" />
</template>
</ai-search-bar>
<ai-search-bar class="mt10">
<template slot="left">
<ai-download :instance="instance" type="primary" url="/app/appvillagerintegraldetail/listExport?exportType=1" :params="params" fileName="个人积分"></ai-download>
</template>
</ai-search-bar>
<ai-table
:tableData="tableData"
:col-configs="colConfigs"
:total="page.total"
style="margin-top: 12px;"
:current.sync="page.current"
:size.sync="page.size"
@getList="getList">
<el-table-column label="操作" slot="options" fixed="right" align="center" width="180">
<template v-slot="{row}">
<div class="table-options">
<el-button type="text" title="家庭成员" @click="familyMember(row)" :disabled="!$permissions('app_appvillagerintegralfamilymember_edit')">家庭成员</el-button>
<el-button type="text" :disabled="!$permissions('app_appvillagerintegralfamily_detail')" title="详情" @click="goDetail(row)">详情</el-button>
</div>
</template>
</el-table-column>
</ai-table>
</template>
</ai-list>
<detail v-if="detailShow" @goBack="goBack" :detailInfo='detailInfo' :instance='instance' :dict='dict'></detail>
<ai-dialog class="family-list"
title="成员列表"
:visible.sync="addMemberVisible"
:customFooter="true"
:destroyOnClose="true"
width="780px">
<ai-table
:tableData="familyList"
:col-configs="familycolConfigs"
:total="familyPage.total"
:current.sync="familyPage.current"
:size.sync="familyPage.size"
:isShowPagination="false"
tableSize="small"
@getList="familyMember(rowInfo)">
<el-table-column label="与户主关系" slot="householdRelation" align="center" width="120">
<template v-slot="{row}">
<span v-if="row.householdIdNumber == row.idNumber">户主</span>
<span v-else>{{dict.getLabel('householdRelation', row.householdRelation)}}</span>
</template>
</el-table-column>
<el-table-column label="身份证号" slot="idNumber" align="center" width="165">
<template v-slot="{row}">
<ai-id mode="show" :show-eyes="false" :value="row.idNumber"/>
</template>
</el-table-column>
</ai-table>
<div class="dialog-footer" slot="footer">
<el-button @click="addMemberVisible=false" size="medium"> </el-button>
</div>
</ai-dialog>
</section>
</template>
<script>
import {mapState} from 'vuex';
import detail from './detail'
export default {
name: 'AppScorePersonal',
label: "个人积分",
props: {
instance: Function,
dict: Object,
permissions: Function
},
components: {detail},
data() {
return {
areaId: '',
searchObj: {
householdName: '',
con: '',
isPositive: ''
},
householdNameList: [{
dictName: '是',
dictValue: '1'
}, {
dictName: '否',
dictValue: '0'
}],
isPositiveList: [{
dictName: '是',
dictValue: '1'
}, {
dictName: '否',
dictValue: '0'
}],
page: {
current: 1,
size: 10,
total: 0
},
familyPage: {
current: 1,
size: 10,
total: 0
},
exportParams: {},
tableData: [],
dialog: {
title: '添加家庭',
visible: false
},
dialogInfo: {
personType: '0',
name: '',
idNumber: '',
phone: '',
villageGroup: '',
status: '',
areaId: '',
householdRelation: '',
avatar: ''
},
addMemberVisible: false,
detailShow: false,
personUrl: '',
familyList: [],
familyId: '',
detailInfo: {},
rowInfo: {}
}
},
computed: {
...mapState(['user']),
params () {
return {
...this.searchObj,
areaId: this.areaId,
exportType: 1
}
},
colConfigs() {
return [
{
prop: 'name',
label: '姓名',
},
{
prop: 'phone',
align: 'center',
label: '联系电话',
},
{
prop: 'residentType',
align: 'center',
label: '类型',
formart: v => this.dict.getLabel('residentType', v)
},
{
prop: 'householdAreaName',
align: 'center',
label: '所在村'
},
{
prop: 'personalIntegral',
align: 'center',
label: '个人积分',
},
{
prop: 'personalUsedIntegral',
align: 'center',
label: '已用积分',
},
{
prop: 'householdName',
align: 'center',
label: '是否户主',
formart: v => v === '1' ? '是' : '否'
}
]
},
familycolConfigs() {
return [
{
prop: 'householdRelation',
align: 'center',
slot: 'householdRelation',
label: '与户主关系',
width: 165,
},
// {
// prop: 'householdRelation',
// align: 'center',
// label: '与户主关系',
// render(h, {row}) {
// return h('span', {}, _.$dict.getLabel('householdRelation', row.householdRelation))
// }
// },
{
prop: 'residentType',
align: 'center',
label: '类型',
formart: v => this.dict.getLabel('residentType', v)
},
{
prop: 'name',
align: 'center',
label: '姓名',
},
{
prop: 'idNumber',
align: 'center',
slot: 'idNumber',
label: '身份证号',
width: 165,
},
{
prop: 'phone',
align: 'center',
label: '联系电话',
width: 120,
}
]
},
formRules() {
let IdNumberPass = (rule, value, callback) => {
if (value) {
console.log(this.idCardNoUtil);
if (this.idCardNoUtil.checkIdCardNo(value)) {
callback();
} else {
callback(new Error("身份证号格式错误"));
}
} else {
callback(new Error("请输入身份证号"));
}
};
if (this.dialog.title.indexOf('家庭') != -1) {
return {
personType: [{required: true, message: "请选择类型", trigger: 'change'}],
name: [{required: true, message: "请填写户主", trigger: 'change'}],
idNumber: [{required: true, validator: IdNumberPass, trigger: 'change'}],
phone: [{required: true, message: "请填写联系电话", trigger: 'blur'}],
villageGroup: [{required: true, message: "请选择所属组", trigger: 'change'}],
status: [{required: true, message: "请选择状态", trigger: 'change'}],
householdRelation: [{required: true, message: "请选择与户主关系", trigger: 'change'}]
}
} else {
return {
personType: [{required: true, message: "请选择类型", trigger: 'change'}],
name: [{required: true, message: "请填写户主", trigger: 'change'}],
idNumber: [{required: true, validator: IdNumberPass, trigger: 'change'}],
villageGroup: [{required: true, message: "请选择所属组", trigger: 'change'}],
status: [{required: true, message: "请选择状态", trigger: 'change'}],
householdRelation: [{required: true, message: "请选择与户主关系", trigger: 'change'}]
}
}
}
},
created() {
this.areaId = this.user.info.areaId;
this.dict.load( 'integralRuleStatus', 'householdRelation', 'residentType');
this.getList();
},
methods: {
getList() {
this.instance.post("/app/appresident/personalIntegral", null, {
params: {
...this.searchObj,
...this.page,
areaId: this.areaId
}
}).then(res => {
if (res.code == 0) {
this.tableData = res.data.records.map(v => {
return v
})
this.page.total = res.data.total
}
})
},
typeChange(val) {
val == '0' ? this.personUrl = '/app/appresident/list?fileStatus=0' : this.personUrl = '/app/apprecurrentpopulation/list?fileStatus=0';
this.dialogInfo.name = "";
this.dialogInfo.idNumber = "";
this.dialogInfo.phone = "";
this.dialogInfo.avatar = "";
this.dialogInfo.areaId = "";
},
add() {
this.dialog.visible = true;
this.dialog.title = '添加家庭';
},
addFamily() {
this.dialog.visible = true;
this.dialog.title = '添加成员';
},
init(formName) {
this.$refs[formName].clearValidate();
Object.keys(this.dialogInfo).forEach(e => {
this.dialogInfo[e] = ''
})
this.dialogInfo.personType = '0';
this.personUrl = '';
},
familyMember (row) {
this.instance.post(`/app/appresident/detail?id=${row.id}`).then(res => {
if (res.code === 0) {
this.familyList = res.data.family
this.familyPage.total = res.data.family.length
this.addMemberVisible = true
}
})
},
goBack() {
this.detailShow = false;
},
goDetail(row) {
this.detailInfo = {...row};
this.detailShow = true;
}
}
}
</script>
<style lang="scss" scoped>
.scoreFamily {
height: 100%;
background: #f3f6f9;
overflow: auto;
.form_div {
width: 380px;
}
.add_btn {
color: #5088FF;
font-size: 14px;
line-height: 36px;
text-align: right;
span {
cursor: pointer;
}
span:nth-child(2) {
margin-left: 4px;
}
}
.iconfont {
cursor: pointer;
}
.iconAll_Profile {
padding: 0 8px;
}
.family-list{
::v-deep .el-table--small{
font-size: 14px!important;
}
}
}
</style>

View File

@@ -0,0 +1,168 @@
<template>
<ai-detail class="family_detail">
<template slot="title">
<ai-title title="个人积分明细" :isShowBack="true" :isShowBottomBorder="true" @onBackClick="$emit('goBack')"></ai-title>
</template>
<template slot="content">
<div class="detail-info">
<div class="detail-info__item">
<h2>姓名</h2>
<span>{{ info.name }}</span>
</div>
<div class="detail-info__item">
<h2>个人积分</h2>
<span style="color: #2266FF;">{{ info.personalIntegral || 0 }}</span>
</div>
<div class="detail-info__item">
<h2>已用积分</h2>
<span style="color: #2266FF;">{{ info.personalUsedIntegral || 0 }}</span>
</div>
</div>
<ai-card title="余额变动明细">
<template #content>
<ai-search-bar>
<template #left>
<ai-select v-model="type" placeholder="请选择类型" @change="page.current=1,getList()" :selectList="dict.getDict('integralDetailType')"/>
</template>
<template #right>
<ai-download
:instance="instance"
url="/app/appvillagerintegraldetail/export"
:disabled="!Boolean(tableData.length)"
:params="{residentId:detailInfo.id,type}"
fileName="余额变动明细">
<el-button type="text" icon="iconfont iconExported">导出</el-button>
</ai-download>
</template>
</ai-search-bar>
<ai-table :tableData="tableData" :col-configs="colConfigs"
:total="page.total" border :dict="dict" :current.sync="page.current" :size.sync="page.size" @getList="getList"/>
</template>
</ai-card>
</template>
</ai-detail>
</template>
<script>
export default {
name: 'balance',
props: {
detailInfo: {
type: Object,
require: true
},
instance: Function,
dict: Object
},
data() {
return {
page: {
current: 1,
size: 10,
total: 0
},
info: {},
type: '',
tableData: []
}
},
created() {
this.dict.load('integralDetailType')
this.getList()
},
computed: {
colConfigs() {
return [
{prop: 'doTime', label: '时间', width: 200},
{prop: "type", label: "类型", dict: "integralDetailType", align: 'center'},
{prop: 'changeIntegral', align: 'center', label: '变动积分', render: (h, {row}) => h('p', `${row.integralCalcType == 1 ? '+' : '-'}${row.changeIntegral}`)},
{prop: 'nowIntegral', align: 'center', label: '剩余积分'},
{prop: 'eventDesc', label: '事件', width: 500}
]
}
},
methods: {
getList() {
this.instance.post(`/app/appresident/detail?id=${this.detailInfo.id}`).then(res => {
if (res?.data) {
this.info = res.data.resident
let {type, info: {id: residentId}} = this
this.instance.post(`/app/appvillagerintegraldetail/IntegralList`, null, {
params: {...this.page, queryType: 1, type, residentId}
}).then(res => {
if (res?.data) {
this.tableData = res.data.records
this.page.total = res.data.total
}
})
}
})
}
}
}
</script>
<style lang="scss" scoped>
.family_detail {
height: 100%;
background-color: #fff;
.detail-info {
display: flex;
align-items: center;
margin-bottom: 20px;
.detail-info__item {
flex: 1;
height: 96px;
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;
}
h2 {
margin-bottom: 8px;
color: #888888;
font-size: 16px;
font-weight: bold;
}
span {
display: block;
line-height: 32px;
font-size: 24px;
font-weight: bold;
color: #222;
}
}
}
.iconExported {
color: #5088FF;
font-size: 12px;
cursor: pointer;
}
.info {
padding: 16px 0 16px 0;
}
.do_type {
height: 56px;
}
.fs-14 {
::v-deep .el-table--small {
font-size: 14px !important;
}
}
}
</style>

View File

@@ -0,0 +1,303 @@
<template>
<section class="AppScoreRules">
<ai-list v-if="permissions('app_appvillagerintegralrule_detail')">
<template slot="title">
<ai-title title="积分规则" isShowBottomBorder></ai-title>
</template>
<template slot="content">
<ai-search-bar bottomBorder>
<template slot="left">
<el-cascader size="small" v-model="search.eventType" placeholder="请选择事件/类型" clearable
:props="{...etOps,checkStrictly:true}" @change="handleTypeSearch" ref="eventTypeSearch"/>
<ai-select
v-model="search.status"
@change="page.current = 1, getList()"
placeholder="请选择状态"
:selectList="dict.getDict('integralRuleStatus')">
</ai-select>
</template>
<template slot="right">
</template>
</ai-search-bar>
<ai-search-bar style="margin-top: 16px;">
<template #left>
<el-button type="primary" icon="iconfont iconAdd" @click="dialog=true">添加</el-button>
</template>
</ai-search-bar>
<ai-table
:tableData="tableData"
:col-configs="colConfigs"
:total="page.total" :dict="dict"
:current.sync="page.current"
:size.sync="page.size"
@getList="getList">
<el-table-column slot="integral" label="分值" align="center">
<template slot-scope="{ row }">
<span
v-if="row.integralValueType == 1">
{{ row.integralStart > 0 ? '+' + row.integralStart : row.integralStart }} ~ {{ row.integralEnd > 0 ? '+' + row.integralEnd : row.integralEnd }}
</span>
<span v-else>{{ row.integral > 0 ? '+' : '' }}{{ row.integral }}</span>
</template>
</el-table-column>
<el-table-column slot="options" label="操作" align="center" fixed="right" width="200">
<template slot-scope="{ row }">
<div class="table-options">
<el-button type="text" :disabled="!permissions('app_appvillagerintegralrule_edit')" @click="changeStatus(row.id, 0)" v-if="row.status == 1">
停用
</el-button>
<el-button type="text" :disabled="!permissions('app_appvillagerintegralrule_edit')" @click="changeStatus(row.id, 1)" v-else>启用</el-button>
<el-button type="text" :disabled="!permissions('app_appvillagerintegralrule_edit')" @click="toEdit(row)">编辑</el-button>
<el-button type="text" :disabled="!permissions('app_appvillagerintegralrule_del')" @click="remove(row.id)">删除</el-button>
</div>
</template>
</el-table-column>
</ai-table>
</template>
</ai-list>
<ai-empty v-else>暂无应用权限</ai-empty>
<ai-dialog :title="dialogTitle" :visible.sync="dialog" @onConfirm="onConfirm" @closed="form={ladderRule: []}" width="700px">
<div class="form_div">
<el-form ref="DialogForm" :model="form" :rules="formRules" size="small" label-suffix="" label-width="100px">
<el-form-item label="事件/类型" prop="eventType">
<el-cascader v-model="form.eventType" :props="etOps" clearable placeholder="请选择" @change="handleTypeForm"
:options="cacheOps"/>
</el-form-item>
<el-form-item label="规则" prop="ruleType" v-if="form.ruleType>-1" required>
<el-row type="flex" justify="space-between">
<div v-text="dict.getLabel('integralRuleRuleType',form.ruleType)"/>
<el-button v-if="form.ruleType==1" type="text" icon="iconfont iconAdd"
@click="form.ladderRule.push({viewCount:null,integral:null})">添加
</el-button>
</el-row>
<el-table v-if="form.ruleType==1" :data="form.ladderRule" size="mini" border stripe>
<el-table-column label="查看人数(人)" align="center">
<template slot-scope="{row}">
<el-input class="tableInput" v-model.number="row.viewCount" clearable placeholder="请输入"/>
</template>
</el-table-column>
<el-table-column label="获得积分(分)" align="center">
<template slot-scope="{row}">
<el-input class="tableInput" v-model="row.integral" clearable placeholder="请输入" type="number"
@keyup.native="row.integral=checkIntegral(row.integral)"/>
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="{row,$index}">
<el-button type="text" @click="handleDelete($index)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-form-item>
<el-form-item label="周期范围" prop="scoringCycle">
<ai-select v-model="form.scoringCycle" :selectList="dict.getDict('integralRuleScoringCycle')"/>
</el-form-item>
<template v-if="form.ruleType==0">
<el-form-item label="奖励次数" prop="numberLimit">
<el-input placeholder="请输入,周期范围内,不填写表示不限制" v-model.number="form.numberLimit" clearable/>
</el-form-item>
<el-form-item label="积分分值" prop="integral">
<el-input placeholder="请输入" v-model="form.integral" clearable/>
</el-form-item>
</template>
</el-form>
</div>
</ai-dialog>
</section>
</template>
<script>
export default {
name: "AppScoreRules",
label: "积分规则",
props: {
instance: Function,
dict: Object,
permissions: Function
},
computed: {
isEdit() {
return !!this.form.id
},
dialogTitle() {
return this.isEdit ? "编辑积分规则" : "添加积分规则"
},
etOps() {
return {
lazy: true,
value: "dictValue",
label: "dictName",
lazyLoad: (node, resolve) => {
if (node.level == 0) resolve(this.dict.getDict('integralRuleEvent'))
else if (node.level == 1) {
let dict = 'integralRuleEvent' + node.value
this.dict.load(dict).then(() => {
let nodes = this.dict.getDict(dict).map(e => ({...e, leaf: true}))
resolve(nodes)
})
}
}
}
},
},
data() {
return {
search: {status: "", eventType: null},
page: {current: 1, size: 10, total: 0},
colConfigs: [
{prop: "event", label: "事件", dict: "integralRuleEvent"},
{prop: "type", label: "类型", dict: "integralRuleEventType"},
{prop: "ruleType", label: "规则", dict: "integralRuleRuleType"},
{prop: "scoringCycle", label: "周期范围", dict: "integralRuleScoringCycle"},
{prop: "status", label: "状态", align: "center", width: 96, dict: "integralRuleStatus"},
{slot: "options", label: "操作", align: "center"},
],
tableData: [],
dialog: false,
form: {ladderRule: []},
formRules: {
eventType: [{required: true, message: "请选择事件/类型", trigger: "change"}],
scoringCycle: [{required: true, message: "请选择周期范围", trigger: "change"}],
integral: [{required: true, pattern: /^\d*[.\d]\d?$/, message: "请输入积分分值,最多保留一位小数"}],
numberLimit: [{pattern: /^\d*$/, message: "请输入正整数"}]
},
cacheOps: []
};
},
created() {
this.dict.load("integralRuleStatus", "integralRuleRuleType", 'integralRuleScoringCycle', 'integralRuleEvent', 'integralRuleEventType').then(() => {
this.getList();
});
},
methods: {
getList() {
this.instance.post(`/app/appvillagerintegralrule/list`, null, {
params: {...this.search, ...this.page},
}).then(res => {
if (res?.data) {
this.tableData = res.data.records;
this.page.total = res.data.total;
}
});
},
toEdit(row) {
this.form = this.$copy(row)
let {ladderRule, event, type} = this.form,
dict = 'integralRuleEvent' + event
this.dict.load(dict).then(() => {
this.form.eventType = [event, type]
this.form.ladderRule = JSON.parse(ladderRule || "[]")
this.cacheOps = this.dict.getDict('integralRuleEvent').map(e => {
if (e.dictValue == event) {
e.children = this.dict.getDict(dict).map(d => ({...d, leaf: true}))
}
return e
})
this.$nextTick(() => {
this.dialog = true
})
})
},
remove(id) {
this.$confirm("删除后不可恢复,是否要删除该事项?", {
type: 'error'
}).then(() => {
this.instance
.post(`/app/appvillagerintegralrule/delete?ids=${id}`)
.then((res) => {
if (res.code == 0) {
this.$message.success("删除成功!");
this.getList();
}
});
});
},
changeStatus(id, status) {
let text = status == 1 ? '启用' : '停用'
this.$confirm(`确定${text}该条规则?`).then(() => {
this.instance.post(`/app/appvillagerintegralrule/enableOrDisable?id=${id}`).then((res) => {
if (res.code == 0) {
this.$message.success(`${text}成功!`)
this.getList();
}
});
});
},
onReset() {
this.page.current = 1
this.search.classification = ""
this.search.integralType = ""
this.search.ruleStatus = ""
this.getList();
},
onConfirm() {
if(this.form.ruleType==1 && !this.form.ladderRule.length) {
return this.$message.error('请添加规则')
}
this.$refs.DialogForm.validate((valid) => {
if (valid) {
let formData = this.$copy(this.form)
formData.ladderRule = JSON.stringify(formData.ladderRule)
formData.integral = formData.integral || 0
this.instance.post(`/app/appvillagerintegralrule/addOrUpdate`, formData).then((res) => {
if (res.code == 0) {
this.$message.success(`${this.isEdit ? '编辑成功' : '添加成功'}`)
this.onReset()
this.dialog = false;
}
});
} else {
return false;
}
});
},
handleTypeSearch(v) {
this.search.event = v?.[0]
this.search.type = v?.[1]
this.page.current = 1
this.$refs.eventTypeSearch.dropDownVisible = false
this.getList()
},
handleTypeForm(v) {
if (this.dialog) {
this.form.event = v?.[0]
this.form.type = v?.[1]
this.form.ruleType = !this.form.event ? null : this.form.event == 3 ? 1 : 0
}
},
handleDelete(i) {
this.$confirm("是否要删除该规则?").then(() => {
this.form.ladderRule.splice(i, 1)
}).catch(() => 0)
},
checkIntegral(v) {
return /\.\d{2,}$/.test(v) ? Math.abs(v).toFixed(1) : Math.abs(v)
}
},
};
</script>
<style lang="scss" scoped>
.AppScoreRules {
height: 100%;
background: #f3f6f9;
::v-deep .ai-list__content--right {
width: 100%;
}
::v-deep .ai-dialog {
.el-cascader {
width: 100%;
}
.tableInput {
& > input {
text-align: center;
border: none;
background: transparent;
}
}
}
}
</style>

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