Detail.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. <template>
  2. <Modal
  3. :show="value"
  4. :title="handle.type"
  5. mode="default"
  6. @close="cancel"
  7. >
  8. <template #content>
  9. <div style="max-height:700px;width:100%;padding:12px 32px 32px 32px;">
  10. <!-- 使用者 详情 状态回复信息行 -->
  11. <div class="stateCon" v-if="handle.type!='新增需求'&&detail.billState!=0&&handle.user">
  12. <div class="state-con-1" v-if="handle.user">
  13. <div><div class="title">状态:</div><Tag type="dot" :color="detail.dot">{{detail.text}}</Tag></div>
  14. <!-- 需求状态 - 0:待提交 1:待回复 2:已接受 3:已拒绝 4:待完善 5:论证中 -->
  15. <div v-if="detail.billState==2||detail.billState==3||detail.billState==4||detail.billState==5"><div>回复人:</div><div v-text="detail.respondent"></div></div>
  16. <div v-if="detail.billState==2||detail.billState==3||detail.billState==4"><div>回复时间:</div><div v-text="toTime(detail.answerTime)"></div></div>
  17. <div v-if="detail.billState==5"><div>预计回复时间:</div><div v-text="toTime(detail.estimateTime)"></div></div>
  18. </div>
  19. <div class="state-con-2" v-if="detail.billState==2||detail.billState==3||detail.billState==4">
  20. <div><div class="title">回复信息:</div><div class="state-con-reply" v-text="detail.reply||'--'"></div></div>
  21. </div>
  22. </div>
  23. <div class="gridCon" v-if="handle.type!='新增需求'&&detail.billState!=0&&(((detail.billState!=4||(detail.billState==4&&handle.type=='详情'))&&handle.user)||!handle.user)">
  24. <div class="gridRow">
  25. <div class="gridCell1">用户名</div><div v-text="detail.userName"></div>
  26. </div>
  27. <div class="gridRow">
  28. <div class="gridCell1">部门</div><div v-text="detail.deptName"></div>
  29. </div>
  30. <div class="gridRow">
  31. <div class="gridCell1">条线</div><div v-text="line[detail.productLine]"></div>
  32. </div>
  33. <div class="gridRow">
  34. <div class="gridCell1">提出时间</div><div v-text="toTime(detail.creationTime)"></div>
  35. </div>
  36. <div class="gridRow">
  37. <div class="gridCell1">编码</div><div v-text="detail.code"></div>
  38. </div>
  39. <div class="gridRow">
  40. <div class="gridCell1">主题</div><div v-text="detail.subject"></div>
  41. </div>
  42. <div class="gridRow">
  43. <div class="gridCell1">需求内容</div><div v-text="detail.content"></div>
  44. </div>
  45. </div>
  46. <!-- 使用者 新增修改 -->
  47. <div class="editCon" v-if="handle.type=='新增需求'||handle.type=='修改需求'">
  48. <div class="editCell">
  49. <div class="editCellTitle">用户名</div>
  50. <Input width="100%" placeholder="用户名" disabled v-model="detail.userName"/>
  51. </div>
  52. <div class="editCell">
  53. <div class="editCellTitle"><em>*</em> 部门</div>
  54. <Input width="100%" placeholder="请输入该用户在钉钉中的部门信息" v-model="detail.deptName"/>
  55. </div>
  56. <div class="editCell">
  57. <div class="editCellTitle"><em>*</em> 条线</div>
  58. <Select
  59. isReadOnly
  60. :selectdata="lineData"
  61. width="536"
  62. v-model="detail.productLine"
  63. :placeholder="'请选择内容'"
  64. hideClear
  65. />
  66. </div>
  67. <div class="editCell">
  68. <div class="editCellTitle"><em>*</em> 主题</div>
  69. <Input placeholder="示例:新增对象-策略" v-model="detail.subject" :maxLength="30"/>
  70. </div>
  71. <div class="editCell">
  72. <div class="editCellTitle"><em>*</em> 需求内容</div>
  73. <Input width="100%" placeholder="请输入内容" type="textarea" :maxLength="210" v-model="detail.content" @input="inputContent" :error-info="errorMsg"/>
  74. </div>
  75. <!-- <div class="editCell">
  76. <div class="editCellTitle"><em>*</em> 需求内容</div>
  77. <el-input
  78. type="textarea"
  79. placeholder="请输入内容"
  80. v-model="detail.userName"
  81. maxlength="30"
  82. show-word-limit
  83. />
  84. </div> -->
  85. </div>
  86. <!-- 编辑者 回复 -->
  87. <div class="replyCon" v-if="handle.type=='回复'||handle.type=='继续回复'">
  88. <div class="replyInfo"><b class="replyInfo1">需求回复</b> <b class="replyInfo2" v-if="handle.type=='继续回复'">上次回复时间:<b class="replyInfo3" v-text="toTime(detail.estimateTime,true)"></b></b></div>
  89. <div>
  90. <radio-group :group-data.sync="stateGroup" type="single" @change="stateChange"/>
  91. </div>
  92. <Input v-if="stateSel!=5" width="100%" placeholder="请输入回复的信息" type="textarea" :maxLength="210" v-model="reply" @input="inputContent" :error-info="errorMsg"/>
  93. <div v-if="stateSel==5" class="estimateTime"><div>预计回复时间</div><PickerDate @change="dateChange" :picker="['day']" placeholder="请选择日期"/></div>
  94. <div></div>
  95. </div>
  96. <!-- 编辑者 详情 状态回复信息行 -->
  97. <div class="stateCon" v-if="handle.type=='详情'&&!handle.user" style="padding-top:14px">
  98. <div class="state-con-1">
  99. <div><div class="title">状态:</div><Tag type="dot" :color="detail.dot">{{detail.text}}</Tag></div>
  100. <!-- 需求状态 - 0:待提交 1:待回复 2:已接受 3:已拒绝 4:待完善 5:论证中 -->
  101. <div v-if="detail.billState==2||detail.billState==3||detail.billState==4"><div>操作时间:</div><div v-text="toTime(detail.answerTime,true)"></div></div>
  102. </div>
  103. <div class="state-con-2" v-if="detail.billState==2||detail.billState==3||detail.billState==4">
  104. <div><div class="title">回复信息:</div><div class="state-con-reply" v-text="detail.reply||'--'"></div></div>
  105. </div>
  106. </div>
  107. </div>
  108. </template>
  109. <template #handle>
  110. <div v-if="handle.type=='新增需求'||handle.type=='修改需求'||handle.type=='回复'||handle.type=='继续回复'">
  111. <Button @click="cancel" :type="cancelButtonType">{{cancelButtonText}}</Button>
  112. <Button v-if="handle.user" @click="save" type="default">保存</Button>
  113. <Button @click="confirm" :type="confirmButtonType">{{confirmButtonText}}</Button>
  114. </div>
  115. </template>
  116. </Modal>
  117. </template>
  118. <script>
  119. import { Modal, Input, Select, Tag, RadioGroup, PickerDate } from 'meri-design'
  120. export default {
  121. components: {
  122. Modal,
  123. Input,
  124. Select,
  125. Tag,
  126. RadioGroup,
  127. PickerDate
  128. },
  129. props: {
  130. value: {}, // 显示隐藏
  131. handle: {
  132. default: {
  133. user: true,
  134. type: '新增需求', // 新增需求 详情 修改需求 回复 继续回复
  135. detail: {}
  136. }
  137. }, // 操作
  138. cancelButtonText: {
  139. default: '取消'
  140. },
  141. cancelButtonType: {
  142. default: 'text'
  143. },
  144. confirmButtonText: {
  145. default: '提交'
  146. },
  147. confirmButtonType: {
  148. default: 'primary'
  149. }
  150. },
  151. data () {
  152. return {
  153. respondent: '',
  154. reply: '',
  155. estimateTime: null,
  156. stateSel: 2,
  157. stateGroup: [
  158. {
  159. id: 2,
  160. name: '接受',
  161. checked: 'checked',
  162. disabled: false
  163. },
  164. {
  165. id: 3,
  166. name: '拒绝',
  167. checked: 'uncheck',
  168. disabled: false
  169. },
  170. {
  171. id: 4,
  172. name: '待完善',
  173. checked: 'uncheck',
  174. disabled: false
  175. },
  176. {
  177. id: 5,
  178. name: '待论证',
  179. checked: 'uncheck',
  180. disabled: false
  181. }
  182. ],
  183. line: { 1: '业务', 2: '研发', 3: '实施' },
  184. lineData: [{ id: 1, name: '业务' }, { id: 2, name: '研发' }, { id: 3, name: '实施' }],
  185. detail: {
  186. userName: '',
  187. deptName: '',
  188. productLine: null,
  189. subject: '',
  190. content: '',
  191. text: '',
  192. dot: '#f0f'
  193. },
  194. errorMsg: ''
  195. }
  196. },
  197. methods: {
  198. dateChange (date) {
  199. this.estimateTime = this.$moment(date, 'YYYY.MM.DD').valueOf()
  200. },
  201. stateChange (e) {
  202. this.stateSel = e[0]
  203. this.reply = ''
  204. this.estimateTime = null
  205. },
  206. toTime (time, format) {
  207. return time ? this.$moment(time).format(format ? 'YYYY.MM.DD' : 'YYYY-MM-DD HH:mm:ss') : '--'
  208. },
  209. // 取消
  210. cancel () {
  211. this.$emit('cancel')
  212. },
  213. confirm () {
  214. if (this.handle.type === '回复' || this.handle.type === '继续回复') {
  215. const temp = {
  216. ids: [this.handle.detail.id],
  217. billState: this.stateSel,
  218. respondent: this.respondent,
  219. reply: this.reply,
  220. estimateTime: this.estimateTime
  221. }
  222. // 校验
  223. let error = ''
  224. if (temp.billState === 5) {
  225. if (!temp.estimateTime)error = '请选择预计回复时间'
  226. } else {
  227. if (!temp.reply || temp.reply.length > 200)error = '填写内容有误,请查验!'
  228. }
  229. if (error) {
  230. this.$pmessage({ type: 'error', message: error })
  231. } else {
  232. this.$emit('confirm', temp)
  233. }
  234. } else {
  235. const check = this.check()
  236. if (check) this.$emit('confirm', check)
  237. }
  238. },
  239. save () {
  240. const check = this.check()
  241. if (check) this.$emit('save', check)
  242. },
  243. inputContent (val) {
  244. if (val.length > 200) {
  245. this.errorMsg = '限制200字符'
  246. } else {
  247. this.errorMsg = ''
  248. }
  249. },
  250. check () {
  251. // 校验
  252. const detail = this.detail
  253. if (!detail.userName || !detail.deptName || !detail.productLine || !detail.subject || !detail.content || detail.content.length > 200) {
  254. this.$pmessage({ type: 'error', message: '填写内容有误,请查验!' })
  255. return false
  256. }
  257. return detail
  258. }
  259. },
  260. mounted () {
  261. console.log(212)
  262. if (this.handle.userName && this.handle.user) { // 新建
  263. this.detail.userName = this.handle.userName
  264. } else if (this.handle.userName && !this.handle.user) { // 回复
  265. this.respondent = this.handle.userName
  266. this.detail = this.handle.detail
  267. if (this.handle.type === '继续回复') {
  268. this.stateGroup[3].disabled = true
  269. }
  270. } else {
  271. this.detail = this.handle.detail
  272. }
  273. }
  274. }
  275. </script>
  276. <style lang="less" scoped>
  277. .editCon{
  278. .editCell{
  279. .editCellTitle{
  280. padding: 8px 0;
  281. em{
  282. color:#F54E45;
  283. }
  284. }
  285. .p-input,.p-textarea{
  286. width: 100% !important;
  287. }
  288. }
  289. }
  290. .stateCon{
  291. color: #646C73;
  292. .title{
  293. color: #1F2429;
  294. }
  295. &>div{
  296. display: flex;
  297. padding: 8px 0;
  298. }
  299. .state-con-1{
  300. /deep/.p-tag-wrapper{
  301. height: 18px !important;
  302. }
  303. &>div {
  304. display: flex;
  305. align-items: center;
  306. padding-left: 20px;
  307. }
  308. &>div:first-child{
  309. padding-left: 0px;
  310. }
  311. }
  312. .state-con-2{
  313. padding-bottom: 0;
  314. }
  315. .state-con-reply{
  316. padding-top: 6px;
  317. font-size: 16px;
  318. line-height: 28px;
  319. }
  320. }
  321. .gridCon {
  322. border: 1px solid #D8D8D8;
  323. margin-top: 12px;
  324. .gridRow {
  325. min-height: 50px;
  326. border-bottom: 1px solid #eff0f1;
  327. display: flex;
  328. .gridCell1 {
  329. width: 82px;
  330. text-align: right;
  331. padding: 0 14px 0 0;
  332. background: #F5F7FA;
  333. color: #646C73;
  334. font-weight: 500;
  335. display: flex;
  336. justify-content: flex-end;
  337. align-items: center;
  338. }
  339. &>div:nth-child(2) {
  340. width: calc(100% - 82px);
  341. padding: 12px;
  342. word-break: break-all;
  343. color: #1F2429;
  344. line-height: 22px;
  345. }
  346. }
  347. .gridRow:last-child{
  348. border-bottom: none;
  349. }
  350. }
  351. .replyCon{
  352. .replyInfo{
  353. padding-top: 20px;
  354. .replyInfo1{
  355. color: #1F2329;
  356. font-weight: 500;
  357. }
  358. .replyInfo2{
  359. color: #646C73;
  360. }
  361. .replyInfo3{
  362. color: #F54E45;;
  363. }
  364. }
  365. .p-input,.p-textarea{
  366. width: 100% !important;
  367. }
  368. .p-radio-group {
  369. padding-left: 0;
  370. }
  371. .estimateTime{
  372. display: flex;
  373. align-items: center;
  374. &>div:first-child{
  375. padding-right: 10px;
  376. }
  377. }
  378. }
  379. </style>